zoukankan      html  css  js  c++  java
  • 序列化器: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
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    MySQL-基本sql命令
    Java for LeetCode 203 Remove Linked List Elements
    Java for LeetCode 202 Happy Number
    Java for LeetCode 201 Bitwise AND of Numbers Range
    Java for LeetCode 200 Number of Islands
    Java for LeetCode 199 Binary Tree Right Side View
    Java for LeetCode 198 House Robber
    Java for LeetCode 191 Number of 1 Bits
    Java for LeetCode 190 Reverse Bits
    Java for LeetCode 189 Rotate Array
  • 原文地址:https://www.cnblogs.com/YZL2333/p/11800317.html
Copyright © 2011-2022 走看看