首页技术文章正文

DRF框架:序列化器字段类型和选项参数

更新时间:2020-08-07 来源:黑马程序员 浏览量:

1. 字段类型和选项参数

本篇文章我们来继续学习序列化器类定义中的字段类型和选项参数。

首先我们来回顾一下序列化器类的基本定义形式:

在定义序列化器类时,我们需要选择对应的字段类型和设置对应的选项参数,接下来我们分别来进行讲解。

2. 字段类型

下面的表格中我们列出了序列化器中常用的字段类型,对于DRF框架中序列化器所有的字段类型,我们可以到 rest_framework.fields 模块中进行查看。

字段字段构造方式
BooleanFieldBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
IntegerFieldIntegerField(max_value=None, min_value=None)
FloatFieldFloatField(max_value=None, min_value=None)
DecimalField

DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)

max_digits: 最多位数

decimal_palces: 小数点位置

DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeFieldTimeField(format=api_settings.TIME_FORMAT, input_formats=None)
ChoiceField

ChoiceField(choices)

choices与Django的用法相同

ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

我们可以发现,序列化器类定义字段类型和Django框架中的字段类型是一样,我们只需知道常用的字段类型就可以了,对于其他字段类型,需要的时候再去查看就可以了。

3. 选项参数

对于序列化器字段的选项参数,分别如下两类:

·通用选项参数:任意字段类型都拥有的参数

·常用选项参数:特定字段类型才拥有的参数

3.1 通用选项参数

通用选项参数有如下常见参数:

参数名称说明
read_only默认False,若设置为True,表明对应字段只在序列化操作时起作用
write_only默认False,若设置为True,表明对应字段只在反序列化操作时起作用
required默认True,表明对应字段在数据校验时必须传入
default序列化和反序列化时使用的默认值
label用于HTML展示API页面时,显示的字段名称,理解为对字段的注释说明即可

对于这些通用的选项参数,我们需要重点理解里面红色部分3个选项参数的作用,接下来我们来对这些选项参数做一些具体的介绍。

示例1:read_only参数 (注意对比设置之前和设置之后的效果)

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    # 此处将age字段的read_only参数设置为True
    age = serializers.IntegerField(read_only=True)
if __name__ == "__main__":
    # 准备数据
    data = {'name': 'laowang', 'age': 18}
    # 数据校验
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 获取校验通过之后的数据
        print('校验通过:', serializer.validated_data)
    else:
        # 获取校验失败之后的错误提示信息
        print('校验失败:', serializer.errors)


示例结果:

1596789553423_序列化器01.png

结果说明:

上面的age字段已经设置的read_only=True,所以在反序列化-数据校验时不必传入,即使传了,也会忽略它的存在。

示例2:write_only参数 (注意对比设置之前和设置之后的效果)

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    # 此处将age字段的write_only参数设置为True
    age = serializers.IntegerField(write_only=True)
if __name__ == "__main__":
    # 创建user对象
    user = User('smart', 18)
    # 将user对象序列化为字典{'name': 'smart', 'age': 18}
    serializer = UserSerializer(user)
    # serializer.data获取序列化之后的字典数据
    print(serializer.data)


示例结果:

1596789565227_序列化器02.png


结果说明:

上面的age字段已经设置的write_only=True,所以在进行序列化操作时会忽略它的存在,因而上面的序列化之后的数据中只会拿user对象name属性的值,而不会拿user对象的age属性的值。

示例3:required参数 (注意对比设置之前和设置之后的效果)

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    # 此处age字段的required参数默认为True
    age = serializers.IntegerField()
if __name__ == "__main__":
    # 准备数据
    data = {'name': 'laowang'}
    # 数据校验
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 获取校验通过之后的数据
        print('校验通过:', serializer.validated_data)
    else:
        # 获取校验失败之后的错误提示信息
        print('校验失败:', serializer.errors)

示例结果:

1596789575137_序列化器03.png


结果说明:

上面的age字段默认required=True,表明数据校验时是必传的,示例中未传递age,所以校验失败。

将上面示例中age字段的required设置为False:

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    # 此处将age字段的required参数设置为False
    age = serializers.IntegerField(required=False)
if __name__ == "__main__":
    # 准备数据
    data = {'name': 'laowang'}
    # 数据校验
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 获取校验通过之后的数据
        print('校验通过:', serializer.validated_data)
    else:
        # 获取校验失败之后的错误提示信息
        print('校验失败:', serializer.errors)

示例结果:

1596789585319_序列化器04.png

结果说明:

上面的age字段设置required=Fasle,表明数据校验时可传可不传,示例中未传递age,校验也能通过。

示例4:default参数 (注意对比设置之前和设置之后的效果)

1)序列化时所使用的默认值

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    age = serializers.IntegerField()
    addr = serializers.CharField(default='默认地址')
if __name__ == "__main__":
    # 创建user对象
    user = User('smart', 18)
    # 将user对象序列化为字典{'name': 'smart', 'age': 18}
    serializer = UserSerializer(user)
    # serializer.data获取序列化之后的字典数据
    print(serializer.data)


示例结果:

1596789596245_序列化器05.png


结果说明:

上面的addr字段设置了一个default默认值,在序列化user对象时,因为user对象中没有addr属性,所以序列化之后的数据中addr使用了默认值。

小提示:如果user对象有addr属性,则序列化之后的字典中addr的值不再使用default设置的默认值。

2)反序列化时所使用的默认值

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField()
    # 注:一旦一个字段设置了default,则这个字段的required默认为False
    age = serializers.IntegerField(default=20)
if __name__ == "__main__":
    # 准备数据
    data = {'name': 'laowang'}
    # 数据校验
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 获取校验通过之后的数据
        print('校验通过:', serializer.validated_data)
    else:
        # 获取校验失败之后的错误提示信息
        print('校验失败:', serializer.errors)

示例结果:

1596789606758_序列化器06.png


结果说明:

上面的age字段设置了一个默认值,校验的data字典中未传递age数据,所以校验之后的数据中age使用了设置的默认值。

小提示:如果反序列化时传递的data中包含age,则校验之后的字典中age的值不再使用default设置的默认值。

3.2 常用选项参数

常用的选项参数有如下几个参数:

小提示:以下4个参数都是只在数据校验时起作用。

参数名称作用
max_length字符串最大长度
min_length字符串最小长度
max_value数字最大值
min_value数字最小值

参数说明:

·max_length和min_length是针对字符串类型的参数;

·max_value和min_value是针对数字类型的参数。

示例1:max_length和min_length

示例结果:

from rest_framework import serializers
class User(object):
    """用户类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器类"""
    name = serializers.CharField(min_length=6, max_length=20)
    # 此处age字段的required参数默认为True
    age = serializers.IntegerField()
if __name__ == "__main__":
    # 准备数据
    data = {'name': 'smart'}
    # 数据校验
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 获取校验通过之后的数据
        print('校验通过:', serializer.validated_data)
    else:
        # 获取校验失败之后的错误提示信息
        print('校验失败:', serializer.errors)


结果说明:

1596789617987_序列化器07.png

上面的name字段设置了min_length=6和max_length=20两个参数,在进行数据校验时,会要求name的长度在6-20之间,因为我们传递的"smart"长度为5,所以校验失败。

4. 内容总结

本次文章我们讲解了以下内容,大家注意结合示例代码来加强对一些常见的选项参数的理解,下次我们来详细讲解一下序列化器的序列化功能。

1)常见的字段类型

2)通用选项参数

3)常用选项参数


猜你喜欢:

python日志模块 logging怎么用?

Python单例设计模式和企业级电商秒杀业务解决方案

Python培训课程

分享到:
在线咨询 我要报名
和我们在线交谈!