【Django】REST_Framework框架——序列化器serializers源码解析

【Django】REST_Framework框架——序列化器serializers源码解析_第1张图片

一、序列化器类——Serializer

1、序列化器的作用

序列化器的使用分两个阶段:

1、在客户端请求时,使用序列化器可以完成对数据的反序列化(将字典格式的数据转化为模型对象)。
2、在服务器响应时,使用序列化器可以完成对数据的序列化(将模型对象转化为字典格式的数据)。

1、反序列化操作,会将前端传递的数据request.data,先通过serializer.is_valid()校验,校验通过调用save()方法,调用ModelSerializer中的create()方法或者Update()方法并且返回instance模型对象(只限于ModelSerializer类)
2、序列化操作,将返回的模型对象instance与序列化器中的字段进行比对那些需要输出,serializer.data为将要输出的数据为字典格式,经过response以后变成json格式字符串

2、Serializer属性中选项参数

参数名称 作用
max_length 最大长度
min_length 最小长度
allow_blank 是否允许为空
trim_whitespace 是否截断空白字符
max_value 最大值
min_value 最小值
参数名称 说明
read_only 该字段仅用于序列化输出,需要序列化输出时设置:read_only=True;默认为False
write_only 该字段仅用于反序列输入,需要序列化输入时设置:write_only=True;默认为False
required 该字段表示在反序列化输入时必须输入
default 反序列化时使用的默认值
allow_null 表明该字段是否允许传入None,默认False
validators 对字段进行校验,定义在字段中
error_message 当字段校验不通过时,报error_message的value值
label 用于HTML展示API页面时,显示的字段名称
help_text 用于HTML展示API页面时,显示的字段帮助提示信息

3、创建Serializer对象

Serializer的构造方法为:

Serializer(instance=None,data=None,**kwargs)
说明:
1、instance接收查询集对象或者模型对象
2、data接收前端传递的数据为json格式
3、除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据

4、反序列化

4.1、数据验证

使用序列化器进行反序列化输入时,需要进行验证,通过后,才能获取验证成功后的数据

serializer.is_valid()=True时:验证过通过;
serializer.is_valid()=False时:验证不通过;
serializer.validated_data:验证通过的数据;
验证失败,可以通过serializer.errors属性获取错误信息,返回字典,包含了字段和字段的错误;如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。

4.2、validators:序列化字段中定义的选项参数

案例1:

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
    validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复')])

案例2


def is_contains_keyword(value):
	is '项目' not in value:
		raise serializers.ValidationError("项目名称中必须包含'项目'关键字")

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
                               validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复'),is_contains_keyword])

4.3、validate_字段名:对字段进行校验

单个字段进行校验:项目名称不能多于10个字

def is_contains_keyword(value):
	is '项目' not in value:
		raise serializers.ValidationError("项目名称中必须包含'项目'关键字")

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
                               validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复'),is_contains_keyword])
	class Meta:
        model=Projects
        fields='__all__'
    
    def validate_name(self,attr:str):
    	if len(attr)>10:
    		raise serializers.ValidationError('项目名称不能多于10个字')
    	return attr

4.4、validate:多字段校验

class RegisterModelSerializer(serializers.ModelSerializer):
    password_confirm = serializers.CharField(label='确认密码', help_text='确认密码',
                                             error_messages={"min_length": "允许输入5-20个字符",
                                                             "max_length": "允许输入5-20个字符", },
                                             write_only=True)
    token = serializers.CharField(label='token', help_text='token', read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'password', 'password_confirm', 'token', 'email']

    # 校验密码与验证码密码
    def validate(self, attrs):
        password=attrs.get('password')
        password=attrs.get('password_confirm')
        if password!=password_confirm:
        	raise serializers.ValidationError('密码和确认密码不一致')
        return attrs

5、反序列化-保存数据

前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象,可以通过定义create()和update()两个方法来实现。

def create(self,validated_data):
	......
	return instance

def update(self,validated_data):
	......
	return instance

二、模型类序列化器——ModelSerializer

如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。
【Django】REST_Framework框架——序列化器serializers源码解析_第2张图片
【Django】REST_Framework框架——序列化器serializers源码解析_第3张图片

父类中虽然提供了create()方法和update()方法,但是方法体是空的,如果子类需要使用,需要重写create()和update()方法

【Django】REST_Framework框架——序列化器serializers源码解析_第4张图片

ModelSerializer与常规的Serializer相同,但提供了:

基于模型类自动生成一系列的字段与模型类中的字段名称一致
包含默认的create()和update()方法的实现

1、指定字段

使用fields来明确字段,__all__表名包含所有字段,

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'

也可以写明具体哪些字段,如

class NewsChannel1Serializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields=['id','url']

使用exclude可以明确排除掉哪些字段

class NewsChannel1Serializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        exclude=['url']

指明只读字段;可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'
        read_only_fields=['url','name']

我们可以使用 extra_kwargs参数为ModelSerializer添加或修改原有的选项参数

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'
        extra_kwargs={
			'name':{'max_length':10,'min_length':1,'required':True}
		}

【Django】REST_Framework框架——序列化器serializers源码解析_第5张图片

你可能感兴趣的:(#,DRF框架,python,开发语言)