一、序列化器类——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类。
父类中虽然提供了create()方法和update()方法,但是方法体是空的,如果子类需要使用,需要重写create()和update()方法
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}
}