序列化器:ModelSerializer

ModelSerializer 类提供了一个快捷方式,可让你基于 Models 自动创建一个 Serializer 类,其中的字段与模型类字段对应。

ModelSerializer 类与常规 Serializer 类相同,不同之处在于:

  • 它会根据模型自动生成一组字段。
  • 它会自动为序列化类生成验证器,例如 unique_together 验证器。
  • 它包含 .create().update() 的简单默认实现。

声明 ModelSerializer 如下所示:

from rest_framework import serializers

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        # 指定对哪个模型进行序列化
        model = Account
        # 指定包含哪些字段
        fields = (‘id‘, ‘account_name‘, ‘users‘, ‘created‘)

默认情况下,该类中的所有模型类字段将被映射为相应的序列化类字段。
任何关系(如模型上的外键)都将映射到 PrimaryKeyRelatedField 。除非在序列化关系文档中指定,否则默认不包括反向关系。


检查 ModelSerializer

序列化类能够生成一个表示字符串,可以让你充分检查其字段的状态。在使用 ModelSerializer 进行工作时,这是特别有用的,你需要确定它为你自动创建了哪些字段和验证器。

为此,需要进入 Django shell,然后导入序列化类,实例化它并用 repr() 打印对象表示形式:

>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
    id = IntegerField(label=‘ID‘, read_only=True)
    name = CharField(allow_blank=True, max_length=100, required=False)
    owner = PrimaryKeyRelatedField(queryset=User.objects.all())

这里会把自动生成的序列化器打印出来。


指定要包含的字段

如果你只希望在模型序列化程序中使用默认字段的子集,则可以使用 fieldsexclude 选项来完成此操作,就像使用 ModelForm 一样。

强烈建议你显式使用 fields 属性序列化的所有字段。这将使你不太可能在模型更改时无意中暴露数据。

比如:

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = (‘id‘, ‘account_name‘, ‘users‘, ‘created‘)

你还可以将 fields 属性设置为特殊值 ‘__all__‘,以指示应该使用模型中的所有字段。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ‘__all__‘

你可以将 exclude 属性设置为从序列化程序中排除的字段列表。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        exclude = (‘users‘,)

fieldsexclude 属性中的名称通常映射到模型类的模型字段。

或者 fields 选项中的名称可以映射成属性或方法。而不会变成模型类中的参数。

从版本 3.3.0 开始,必须提供其中一个属性 fieldsexclude


指定嵌套序列化

默认的 ModelSerializer 使用主键进行关联,但你也可以使用 depth 选项轻松生成嵌套表示(自关联)。

为了便于理解,这里我们用上一篇的 User 和 Profile 的关联模型来举例。

# serializers.py

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = (‘city‘, ‘owner‘)
        depth = 1

现在设定了 depth = 1 ,当我们在 shell 中执行下列操作时:

>>> u = Profile.objects.get(pk=1)
>>> serializer = ProfileSerializer(u)
>>> serializer.data

打印出来的 owner 将不仅仅是对应的 User 的主键,而是包括该 User 的所有字段:

ReturnDict([(‘city‘, ‘shanghai‘),
            (‘owner‘,
             OrderedDict([(‘id‘, 1),
                          (‘password‘,‘xxx‘),
                          (‘last_login‘, ‘2018-05-03T15:08:04.022687Z‘),
                          (‘is_superuser‘, True),
                          (‘username‘, ‘diego‘),
                          (‘first_name‘, ‘‘),
                          (‘last_name‘, ‘‘),
                          (‘email‘, ‘‘),
                          (‘is_staff‘, True),
                          (‘is_active‘, True),
                          (‘date_joined‘, ‘2018-04-01T15:01:29.451391Z‘),
                          (‘groups‘, []),
                          (‘user_permissions‘, [])]))])

默认情况下 depth = 0,这时候序列化的关联对象将只包含该对象的主键:

ReturnDict([(‘city‘, ‘shanghai‘), (‘owner‘, 1)])

显式指定字段

你可以将额外的字段添加到 ModelSerializer,或者通过在类上声明字段来覆盖默认字段,就像你对 Serializer 类所做的那样。

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source=‘get_absolute_url‘, read_only=True)
    groups = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Account

额外的字段可以对应于模型上的任何属性或可调用的字段。


指定只读字段

你可能希望将多个字段指定为只读。不要显式给每个字段添加 read_only = True 属性,你可以使用快捷方式 Meta 选项 read_only_fields

该选项应该是字段名称的列表或元组,声明如下:

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = (‘id‘, ‘account_name‘, ‘users‘, ‘created‘)
        read_only_fields = (‘account_name‘,)

含有 editable = False 的模型字段,AutoField 字段默认设置为只读,并且不需要添加到 read_only_fields 选项。

注意: 有一种特殊情况,只读字段是模型级别的 unique_together 约束的一部分。在这种情况下,序列化类需要验证约束该字段,但也不能由用户编辑。

处理这个问题的正确方法是在序列化类中明确指定字段,同时提供 read_only = True 和 default = ... 关键字参数。

其中一个例子是与当前认证 User 的只读关系,它与另一个标识符是 unique_together 。在这种情况下,你会像这样声明用户字段:

user = serializers.PrimaryKeyRelatedField(
    read_only=True,
    default=serializers.CurrentUserDefault()
    )

其他关键字参数

还有一个快捷方式允许你使用 extra_kwargs 选项在字段上指定任意附加关键字参数。与 read_only_fields 的情况一样,这意味着你不需要在序列化类中显式声明该字段。

该选项是一个字典,将字段名称映射到关键字参数字典。例如:

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (‘email‘, ‘username‘, ‘password‘)
        extra_kwargs = {‘password‘: {‘write_only‘: True}}

    def create(self, validated_data):
        user = User(
            email=validated_data[‘email‘],
            username=validated_data[‘username‘]
        )
        user.set_password(validated_data[‘password‘])
        user.save()
        return user

作者:SingleDiego
链接:https://www.jianshu.com/p/099d8c688384
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/YZL2333/p/11800317.html

时间: 2024-08-30 09:42:33

序列化器:ModelSerializer的相关文章

模型类序列化器

模型类序列化器 DRF提供了模型类序列化器: ModelSerializer 作用: 简化对应django模型类的序列化器的定义 ModelSerializer与常规的Serializer相同,但提供了: 基于模型类自动生成一系列字段 基于模型类自动为 Serializer 生成 validators,比如字段唯一的校验器 包含默认的 create() 和 update() 的实现 1. 定义 比如我们创建一个 DepartmentSerializer2 class DepartmentSeri

序列化器的理解

其实就是Django RESTful Framework RESTful一种API的命名风格,主要因为前后端分离开发出现 前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到 RESTful风格:数据应该是名词,而动词由HTTP的请求方式来体现 RESTful风格的API给前端返回 结果对象,无论什么请求方式 "' 特点: 反复重复 因为不论什么请求方式,都需要给前端返回对象内容,就是json格式的 所以每次如果有查询的结果对象都需要遍历成字典,和flask相同 如果不是get请求

drf序列化器serializers.SerializerMethodField()的用法

为什么DRF中有时候返回的json中图片是带域名的,有时候是不带域名的呢? 解析: 带域名的结果是在view中对模型类序列化的,DRF在序列化图片的时候 会检查上下文有没有request,如果有,就给图片加上域名, 比如说我们视图用的是apiview(): 我们需要序列化数据的时候,加  context={"request":request} TestSerilaizer(instance=instance, context={"request":request})

drf序列化器的实例

应用目录结构: views.py from django.shortcuts import render # Create your views here. from django.views import View from django.http import JsonResponse, QueryDict from bookset.models import BookInfo #导入序列化列 from .serializers import BookInfoSerializer #####

Cf序列化器-Serializer解析

Cf序列化器-Serializer 定义序列化器 Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer. 例如,我们已有了一个数据库模型类BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name='名称') bpub_date = models.DateFiel

16-DRF工程搭建与序列化器

1.DRF工程搭建 环境安装与配置 DRF是以Django扩展应用的方式提供的,所以我们可以直接利用Django环境,而无需创建(先创建Django环境). 1.安装DRF pip3 install djangorestframework 2.添加rest_framework应用 在django工程上的settings.py的INSTALLED_APPS中添加“rest_framework” INSTALLED_APPS = [ ... 'rest_framework', ] 使用Django

DRF序列化器的使用

序列化器的使用 序列化器的使用分两个阶段: 在客户端请求时,使用序列化器可以完成对数据的反序列化. 在服务器响应时,使用序列化器可以完成对数据的序列化. 序列化的基本使用 使用的还是上一篇博文中使用的数据库 先查询出一个学生对象 from students.models import Student student = Student.objects.get(id=3) 构造序列化器对象 from .serializers import StudentSerializer serializer

DjangoRestful 递归嵌套序列化器实现

**** 由于博客园不支持markdown语法,所以推荐以下链接阅读: 原创 https://blog.csdn.net/weixin_42495873/article/details/89433542 # Django嵌套递归序列化器实现 **最近在做自己的项目,需要返回评论表相关数据,我的评论表设计的是这样的,父id为空则是等级最高的父评论,然后依次为子.孙子...评论信息关联,类似于省市级三级联动,不过这个评论表的深度可以更深** ![我的评论表](https://img-blog.csd

关于定义序列化器时,read_only和write_only有什么作用

关于序列化和反序列化 ? 在谈论前,先说一下序列化和反序列化,这两个概念最初是在学习json的时候提出来的,回头来看,其实可以用最初的理解就可以了 序列化就是将对象转化方便传输和存储字节序列,例如json.dumps就是序列化(狭义的序列化,将字典转化为json字符串),这样得到的json字符串不仅直接可以在其他语言使用(跨平台比较好),而且可以在前后端进行传输交互(drf序列化器) 反序列化恰恰相反,而是将字节序列转化为对象,json.loads是将json字符串转化为字典,是狭义的反序列化(