DRF数据反序列化

一、数据反序列化使用

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)、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("年级输入错误!")
复制代码

备注:

value的值是前端传进来字典中某一个key的value,这里要校验的是哪个字段,value对应的就是哪个字段的值

(2)、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("年级输入错误!")
复制代码

备注:

attrs指的是前端传进来的整个字典

使用:

复制代码
(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')]}
复制代码

(3)、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)

结果:

二、保存

如果在验证成功后,想要基于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中查看确实更新了数据

 参考博客:

https://blog.csdn.net/weixin_46005957/article/details/129014306

posted @   未来可期_Durant  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2021-07-18 Vue|vue-cli的安装
2021-07-18 Vue|vue ui启动没有反应解决方案
点击右上角即可分享
微信分享提示