前言
本博客是接着上个博客编写的,可以点这里查看
一、数据反序列化使用
1、基本使用
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
使用:
>>> from demo.serializer import ClassInfoSerializer
>>> data = {'number': '一', 'grade': '三年级'}
>>> serializer = ClassInfoSerializer(data=data)
>>> serializer.is_valid()
False
>>> serializer.errors
{'number': [ErrorDetail(string='A valid integer is required.', code='invalid')]}
2、自定义验证
如果觉得提供的验证方法不够用,还可以自定义验证,有以下三种方法:
(1)validators
在字段中添加validators选项参数,也可以补充验证行为,修改代码:
# 验证函数
def about_grade(value):
if not (value == '一年级' or value == '二年级' or value == '三年级'):
raise serializers.ValidationError("年级输入错误!")
class ClassInfoSerializer(serializers.Serializer):
"""班级数据序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
number = serializers.IntegerField(label='班级编号', required=False)
grade = serializers.CharField(label='年级', max_length=3, required=False, validators=[about_grade])
studentinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 添加
使用:
>>> from demo.serializers import ClassInfoSerializer
>>> data = {'grade': '四年级'}
>>> serializer = ClassInfoSerializer(data=data)
结果
(2)validate_<field_name>
要对<field_name>字段进行验证,还可以将代码修改如下:
class ClassInfoSerializer(serializers.Serializer):
"""班级数据序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
number = serializers.IntegerField(label='班级编号', required=False)
grade = serializers.CharField(label='年级', max_length=3, required=False)
studentinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 添加
def validate_grade(self, value):
if not (value == '一年级' or value == '二年级' or value == '三年级'):
raise serializers.ValidationError("年级输入错误!")
使用:
>>> from demo.serializers import ClassInfoSerializer
>>> data = {'grade': '四年级'}
>>> serializer = ClassInfoSerializer(data=data)
结果:
(3)validate
如果需要同时对多个字段进行比较验证时,可以定义validate方法来验证,代码修改如下:
class ClassInfoSerializer(serializers.Serializer):
"""班级数据序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
number = serializers.IntegerField(label='班级编号', required=False)
grade = serializers.CharField(label='年级', max_length=3, required=False)
studentinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 添加
def validate(self, attrs):
number =attrs['number']
grade = attrs['grade']
if number > 10:
raise serializers.ValidationError("number不能大于10")
if not (grade == '一年级' or grade == '二年级' or grade == '三年级'):
raise serializers.ValidationError("年级输入错误!")
使用:
(InteractiveConsole)
>>> from demo.serializers import ClassInfoSerializer
>>> data = {'number': 11, 'grade': '四年级'}
>>> serializer = ClassInfoSerializer(data=data)
>>> serializer.is_valid()
False
>>> serializer.errors
{'non_field_errors': [ErrorDetail(string='number不能大于10', code='invalid')]}
>>> data = {'number': 5, 'grade': '四年级'}
>>> serializer = ClassInfoSerializer(data=data)
>>> serializer.is_valid()
False
>>> serializer.errors
{'non_field_errors': [ErrorDetail(string='年级输入错误!', code='invalid')]}
二、保存
如果在验证成功后,想要基于validated_data完成数据对象的创建,可以通过实现create()和update()两个方法来实现(在序列化器类里面添加)。添加代码如下:
def create(self, validated_data):
"""新建"""
return ClassInfo.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.number = validated_data.get('number', instance.number)
instance.grade = validated_data.get('grade', instance.grade)
instance.save()
return instance
实现了上述两个方法后,在反序列化数据的时候,就可以通过save()方法返回一个数据对象实例了。
如果创建序列化器对象的时候,传递data数据的时候,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,则调用save()方法的时候,update()被调用。
使用:
添加:
>>> from demo.serializers import ClassInfoSerializer
>>> data = {'number': 2, 'grade': '三年级'}
>>> serializer = ClassInfoSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
<ClassInfo: ClassInfo object (4)>
结果:
在navicat中查看确实添加了数据
更新:
>>> from demo.models import ClassInfo
>>> Class_data = ClassInfo.objects.get(id=2)
>>> data = {'number': 3, 'grade': '三年级'}
>>> serializer = ClassInfoSerializer(Class_data, data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
<ClassInfo: ClassInfo object (2)>
结果:
在navicat中查看确实更新了数据
下一章:DRF学习笔记(三):模型类序列化器ModelSerializer