• 序列化器: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
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    java栈的实现复习
    条件判断语句--linux
    转义符&脚本参数--linux
    linux备份脚本-模板
    github的搜索使用技巧
    sonarqube7.9安装部署(linux)
    openjdk与oraclejdk下载
    gitlab重写历史,清理历史大文件
    nexus私服搭建过程
    nexus私服关联本地maven配置
  • 原文地址:https://www.cnblogs.com/YZL2333/p/11800317.html
Copyright © 2020-2023  润新知