心蓝的博客 心蓝的博客
首页
  • 零基础

    • python零基础入门
  • 专项

    • 正则表达式
  • web框架

    • django框架
    • drf
技术
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档

心蓝

人生苦短,我用python
首页
  • 零基础

    • python零基础入门
  • 专项

    • 正则表达式
  • web框架

    • django框架
    • drf
技术
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • 零基础

  • 专项

  • web框架

    • django框架

    • drf

      • 简介
      • 序列化器
      • 请求和响应
      • 类视图
      • 视图集和路由器
      • 序列化器补充
        • 常用序列化器字段
          • CharField
          • RegexField
          • IntergerField
          • FloatField
          • DecimalField
        • 核心参数
          • read_only
          • write_only
          • required
          • default
          • allow_null
          • source
          • validators
          • error_messages
          • label
          • help_text
        • 关系字段
          • StringRelatedField
          • 参数
          • PrimaryKeyRelatedField
          • 参数
          • HyperlinkedRelatedField
          • 参数
          • SlugRelatedField
          • 参数
        • 嵌套关系
        • 模型序列化器
          • 检查一个模型序列化器
          • 指定包含字段
          • 指定内嵌序列化
          • 显示指定额外字段
          • 指定只读字段
          • 额外的关键字参数
        • 反序列化校验
          • 字段级验证
          • 对象级验证
          • 验证器
      • 身份验证与权限
      • 分页与限流
  • python
  • web框架
  • drf
心蓝
2022-12-26
目录

序列化器补充

# 序列化器补充

# 常用序列化器字段

像模型的字段对应数据库字段类型一样,序列化器也有不同的字段类,用来对应不同的数据类型,在序列化,反序列化时进行类型转换和数据校验。

# CharField

文本字段,可以验证文本小于max_length大于min_length。

password = serializers.CharField(max_length=20, min_length=6)
1

# RegexField

文本字段,可以验证文本是否匹配给定正则表达式。

phone = serializers.RegexField(r'^1[3-9]\d{9}$')
1

# IntergerField

整数字段,可以验证整数小于max_value,大于min_value。

age = serializers.IntergerField(max_value=200, min_value=0)
1

# FloatField

实数字段,可以验证整数小于max_value,大于min_value。

salary = serializers.FloatField(min_value=0)
1

# DecimalField

高精度浮点数。

更多字段详见官方文档 (opens new window)

# 核心参数

每个序列化器字段类实例化时都会接收一些参数,一些字段还会接受额外的参数,下面的参数是字段核心参数,所有的字段类都支持。

# read_only

字段只读,默认值为False。只读字段只会包含在序列化输出中,创建修改对象时不会包含该字段,即使输入了也会被忽略。

# write_only

字段只写,默认值为False。和read_only相反,序列化时不包含,创建修改对象时必须包含该字段。

# required

字段必须,默认值为True。必须字段在创建修改对象时必须包含,否则抛出异常。当设置为False时,在创建修改对象时可以不用包含该字段。

# default

默认值。如果一个字段设置了默认值,那么在反序列化时,如果没有提供该字段,则使用默认值进行填充。

在进行局部更新时,default不会应用。因为局部更新时,只有更新的字段会被校验和返回。

还可以设置一个函数或者一个可调用对象,

可以设置为一个函数或其他可调用对象,在这种情况下,会使用调用后的结果进行填充。调用时,它将不接收任何参数。如果可调用对象有一个requires_context = True的属性,那么序列化字段会被当做参数传入。例如:

class CurrentUserDefault:
    """
    May be applied as a `default=...` value on a serializer field.
    Returns the current user.
    """
    requires_context = True

    def __call__(self, serializer_field):
        return serializer_field.context['request'].user
1
2
3
4
5
6
7
8
9

在序列化实例时,如果实例中不存在对象属性或字典键,将使用default的值填充。

注意,设置默认值意味着该字段不是必需的。同时包含默认和必需的关键字参数是无效的,将引发错误。

# allow_null

通常,如果将None传递给序列化器字段,将引发错误。如果None应该被认为是一个有效值,则将该关键字参数设置为True。

注意,如果没有显式的默认值,将该参数设置为True将意味着序列化输出的默认值为None,但这并不意味着输入反序列化是默认的。

默认值为False

# source

将用于填充字段的属性的名称。可以是一个只接受self参数的方法, 比如URLField(source='get_absolute_url'),或者是一个句点法的属性,比如CharField(source='channel.name')。

当使用句点法序列化字段时,如果在属性遍历期间没有任何对象或为空,则可能需要提供一个默认值。

默认值为字段的名称。

# validators

应该应用到输入字段的验证器函数的列表,它要么引发验证错误,要么简单地返回。验证器函数通常应该引发serializers.ValidationError,但Django内置的ValidationError也被支持,以便与Django或第三方Django包中定义的验证器兼容。

# error_messages

错误消息字典。

# label

一个短文本字符串,可以用作HTML表单字段或其他描述性元素中的字段名。

# help_text

可以在HTML表单字段或其他描述性元素中用作字段描述的文本字符串。

# 关系字段

关系字段用来表达模型关系。它们可以应用于ForeignKey, ManyToManyField和OneToOneField关系。

通常使用模型序列化器时,将自动生成序列化字段和关系。

# StringRelatedField

StringRelatedField可以使用关系目标的__str__方法来表示。

例如:

class StudentSerializer(serializers.ModelSerializer):
    # 序列化后显示channel实例的__str__返回的值
    channel = serializers.StringRelatedField()

    class Meta:
        model = Student
        fields = '__all__'

1
2
3
4
5
6
7
8

序列化学生表示如下:

{
    'id': 3, 
    'channel': '抖音', 
    'name': '赵六', 
    ...
}

1
2
3
4
5
6
7

这个字段只读。

# 参数

  • many-如果应用于一对多关系,则应该将此参数设置为True。

# PrimaryKeyRelatedField

PrimaryKeyRelatedField可以使用关系目标的主键来表示。

例如:

class StudentSerializer(serializers.ModelSerializer):
    # 序列化后显示channel实例的__str__返回的值
    channel = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Student
        fields = '__all__'
1
2
3
4
5
6
7

序列化学生表示如下:

{
    'id': 3, 
    'channel': 1, 
    'name': '赵六', 
    ...
}
1
2
3
4
5
6

默认情况下,这个字段是可读写的,可以使用read_only设置为只读。

# 参数

  • queryset- 验证字段输入时用于模型实例查找的queryset。关系必须显式设置一个queryset,或者设置read_only=True。
  • many - 如果应用于一对多关系,则应该将此参数设置为True。
  • allow_null - 如果设置为True,该字段将接受None的值或空字符串的可空关系。默认是False
  • pk_field - 设置为一个字段来控制对主键值的序列化/反序列化。

# HyperlinkedRelatedField

HyperlinkedRelatedField使用一个超链接来表示关系目标。

例如:

class StudentSerializer(serializers.ModelSerializer):
    channel = serializers.HyperlinkedRelatedField(read_only=True, view_name='channel-detail')

    class Meta:
        model = Student
        fields = '__all__'
1
2
3
4
5
6

序列化学生表示如下:

{
    'id': 3, 
    'channel': 'http://127.0.0.1:8000/channel/1/', 
    'name': '赵六', 
    ...
}
1
2
3
4
5
6

默认情况下,这个字段是可读写的,可以使用read_only设置为只读。

注意:该字段是为映射到一个URL的对象设计的,该URL接受一个URL关键字参数,使用lookup_field和lookup_url_kwarg参数设置。

这仅适用于URL中包含一个主键或slug参数的URL。

# 参数

view_name - 关系对象的视图名称。这个参数是必须的。

queryset - 验证字段输入时用于模型实例查找的queryset。关系必须显式设置一个queryset,或者设置read_only=True。

many - 如果应用于一对多关系,则应该将此参数设置为True。

allow_null - 如果设置为True,该字段将接受None的值或空字符串的可空关系。默认是False

lookup_field - 应用于查询的字段。应该对应于被引用视图上的URL关键字参数。默认为pk

lookup_url_kwarg - URL配置文件中定义的关键字参数的名称,对应于查找字段。默认使用与lookup_field相同的值。

format - 如果使用格式后缀,超链接字段将为目标使用相同的格式后缀,除非使用format参数重写。

# SlugRelatedField

SlugRelatedField使用目标上的某个字段来表示关系。

例如:

class StudentSerializer(serializers.ModelSerializer):
    channel = serializers.SlugRelatedField(read_only=True, slug_field='name')

    class Meta:
        model = Student
        fields = '__all__'
1
2
3
4
5
6

序列化学生表示如下:

{
    'id': 3, 
    'channel': '抖音', 
    'name': '赵六', 
    ...
}
1
2
3
4
5
6

默认情况下,这个字段是可读写的,可以使用read_only设置为只读。

当使用SlugRelatedField作为读写字段时,您通常需要确保slug字段对应的模型字段设置了unique=True。

# 参数

slug_field - 目标上应该用来表示它的字段。这应该是唯一标识任何给定实例的字段。这应该是必须的。

queryset - 验证字段输入时用于模型实例查找的queryset。关系必须显式设置一个queryset,或者设置read_only=True。

many - 如果应用于一对多关系,则应该将此参数设置为True。

allow_null - 如果设置为True,该字段将接受None的值或空字符串的可空关系。默认是False

# 嵌套关系

序列化器还可以进行嵌套表示。例如:

class ChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Channel
        fields = '__all__'


class StudentSerializer(serializers.ModelSerializer):
    qq = serializers.CharField(allow_blank=True, allow_null=True, help_text='qq号码', label='Qq号码', max_length=20, required=False,
                   validators=[ UniqueValidator(queryset=Student.objects.all())],
                               error_messages={
                                   'max_length': 'qq号码长度大于20位'
                               })
    phone = serializers.RegexField(r'^1[3-9]\d{9}$',allow_blank=True, allow_null=True, help_text='手机号码', label='手机号码', max_length=11, min_length=11, required
    =False, validators=[ UniqueValidator(queryset=Student.objects.all())])
	channel = ChannelSerializer(read_only=True)
    # 元信息
    class Meta:
        # 指定根据哪个模型生成序列化器
        model = Student
        # 指定序列化哪些字段
        # fields = ['id', 'name', 'sex']
        # 所有字段
        fields = '__all__'
        # fields = ['id', 'name', 'channel_name']
        # 排除
        # exclude = ['id']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 模型序列化器

# 检查一个模型序列化器

直接打印模型序列化器的实例

# 指定包含字段

 fields = ['id', 'account_name', 'users', 'created']  # 显示指定
 fields = '__all__'  # 所有字段
 exclude = ['users']  # 排除字段
 
1
2
3
4

# 指定内嵌序列化

默认的ModelSerializer使用主键作为关系,但你也可以使用depth选项轻松地生成嵌套表示:

class StudentSerializer(serializers.ModelSerializer):
	...
    class Meta:
        model = Student
        fields = '__all__'
        depth = 1
1
2
3
4
5
6

应该将depth选项设置为一个整数值,表示嵌套的深度。如果想要自定义序列化的方式,需要自己定义字段。

# 显示指定额外字段

你可以通过在类上声明字段来向ModelSerializer添加额外的字段,或者覆盖默认字段,就像定义普通的Serializer类一样。

class StudentSerializer(serializers.ModelSerializer):
    channel_name = serializers.CharField(source='channel.name')
    class Meta:    
        model = Student   
        fields = '__all__'
1
2
3
4
5

# 指定只读字段

如果希望将多个字段指定为只读。你可以使用快捷的Meta选项read_only_fields,而不是使用read_only=True属性显式地添加每个字段。

class StudentSerializer(serializers.ModelSerializer):
    channel_name = serializers.CharField(source='channel.name')
    class Meta:    
        model = Student   
        fields = '__all__'
        read_only_fields = ['channel_name']
1
2
3
4
5
6

# 额外的关键字参数

还有一个快捷方式,允许你使用extra_kwargs选项在字段上指定任意额外的关键字参数。与read_only_fields的情况一样,这意味着你不需要在序列化器上显式声明该字段。这个选项是一个字典,将字段名映射到关键字参数的字典。例如:

class StudentSerializer(serializers.ModelSerializer):
	...
    # channel = ChannelSerializer(read_only=True)
    # 元信息
    class Meta:
        # 指定根据哪个模型生成序列化器
        model = Student
        # 指定序列化哪些字段
        # fields = ['id', 'name', 'sex']
        # 所有字段
        fields = '__all__'
      	extra_kwargs = {
            'qq': {'error_messages':{'max_length':'qq号码长度大于20位'}}
        }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 反序列化校验

反序列化数据时,始终需要在尝试访问已验证数据或保存对象实例之前调用is_valid()。如果发生任何验证错误,序列化器对象的.errors属性将包含一个字典,表示生成的错误消息。

{'phone': [ErrorDetail(string='请确保这个字段至少包含 11 个字符。', code='min_length'), ErrorDetail(string='输
入值不匹配要求的模式。', code='invalid')]}
1
2

字典中的每个键都将是字段名称,值将是与该字段对应的任何错误消息的字符串列表。non_field_errors将列出任何一般验证错误。

# 字段级验证

可以通过向子类添加.validate_<field_name>方法来指定自定义字段级验证。这些方法采用单个参数,即需要验证的字段值。validate_<field_name>方法应该返回经过验证的值或引发serializers.ValidationError. 例如:

class StudentSerializer(serializers.ModelSerializer):
	...

    def validate_phone(self, value):
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('请输入正确的手机号码!')
        return value

    class Meta:
        model = Student
        fields = '__all__'

1
2
3
4
5
6
7
8
9
10
11
12

如果<field_name>在序列化程序上声明了参数required=False,如果不包含该字段,则不会执行此验证步骤。

# 对象级验证

要执行需要访问多个字段的任何其他验证,请添加一个调用.validate()到你的Serializer子类的方法。此方法采用单个参数,即字段值字典

class StudentSerializer(serializers.ModelSerializer):
	...

    def validate(self, data):
        if not (data['phone'] and data['qq']):
			raise serializer.ValidationError('请同时提供qq和电话号码')
        return data
    class Meta:
        model = Student
        fields = '__all__'
1
2
3
4
5
6
7
8
9
10

# 验证器

序列化器上的各个字段还可以包含验证器,方法是在字段实例上声明它们,例如:

def validate_phone(value):
    if not re.match(r'^1[3-9]\d{9}$', value):
        raise serializers.ValidationError('请输入正确的手机号码!')
        
class StudentSerializer(serializers.ModelSerializer):
    phone = serializers.CharField(validators=[validate_phone])
1
2
3
4
5
6

序列化程序类还可以包括应用于完整字段数据集的可重用验证器。这些验证器通过在内部Meta类中声明它们来包含,如下所示:

class EventSerializer(serializers.Serializer):
    name = serializers.CharField()
    room_number = serializers.IntegerField(choices=[101, 102, 103, 201])
    date = serializers.DateField()

    class Meta:
        # Each room only has one event per day.
        validators = [
            UniqueTogetherValidator(
                queryset=Event.objects.all(),
                fields=['room_number', 'date']
            )
        ]
1
2
3
4
5
6
7
8
9
10
11
12
13

有关更多信息,请参阅验证器文档 (opens new window)。

本文完,感谢你的耐心阅读,如有需要可加我微信,备注「博客」并说明原因,我们一起进步,下次见。

#drf
上次更新: 2022/12/26, 16:59:39
视图集和路由器
身份验证与权限

← 视图集和路由器 身份验证与权限→

最近更新
01
requests让接口测试如此简单 原创
03-31
02
最简明的python正则教程
03-30
03
pycharm激活码
12-30
更多文章>
Theme by Vdoing | Copyright © 2019-2025 心蓝
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式