首页 > 其他 > 详细

DRF框架之Serializer序列化器的反序列化操作

时间:2020-02-07 18:28:34      阅读:93      评论:0      收藏:0      [点我收藏+]

昨天,我们完成了Serializer序列化器的反序列化操作,那么今天我们就来学习Serializer序列化器的最后一点知识,反序列化操作。

首先,我们定要明确什么是反序列化操作?

反序列化操作:JOSN数据 --> 字典数据 -->验证通过的字典数据 --> 模型数据

我们在进行反序列化操作时,首先要保证就是拿到的字典数据一定要通过认证。

反序列化操作的步骤:

1. 定义一个序列化器(这里我们采用昨天定义好的序列化器即可)。

class BookInfoSerializer(serializers.Serializer):
    ‘‘‘定义图书序Serializer序列化器‘‘‘
    # 这里的字段需要和模型类中的字段名、字段类型、约束一致
    id = serializers.IntegerField(label=ID, read_only=True)
    btitle = serializers.CharField(label=名称, max_length=20)
    bpub_date = serializers.DateField(label=发布日期, required=False)
    bread = serializers.IntegerField(label=阅读量, required=False)
    bcomment = serializers.IntegerField(label=评论量, required=False)

2. 准备JSON数据或字典数据

data = {btitle:大话西游,bpub_date:2020-02-06}

3. 验证字典数据

我们使用序列化器对象点出is_valid()方法进行验证,验证成功返回True,否则返回False。

3.1 验证通过

当字典数据通过校验时,我们可以通过序列化器对象点出validated_data属性获取到校验成功后的字典数据

>>> data = {btitle:大话西游,bpub_date:2020-02-06}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([(btitle, 大话西游), (bpub_date, datetime.date(2020, 2, 6))])

3.2 验证未通过

当字典数据未通过校验时,我们可以通过序列化器对象点出errors属性获取到错误信息

>>> data = {bpub_date: 123}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.validated_data
{}
>>> s.errors
{btitle: [ErrorDetail(string=This field is required., code=required)], bpub_date: [ErrorDetail(string=Date has wrong format. Use one of these formats instead: YYYY-MM-DD., code=invalid)]}

3.3 对单一字段进行验证

我们需要在序列化器类中定义一个名字为(validate_字段名)的方法,来补充验证逻辑。

def validate_btitle(self, value):
    ‘‘‘
    对btitle字段进行验补充
    :param value: 前段传递的btitle数据
    :return: 验证成功:返回value;验证失败:返回错误信息
    ‘‘‘   

当验证失败时,我们使用raise抛出异常的方式来返回错误信息。

例如:

    # 补充单一字段的验证逻辑
    def validate_btitle(self, value):
        ‘‘‘
        对btitle字段进行验补充
        :param value: 前段传递的btitle数据
        :return: 验证成功:返回value;验证失败:返回错误信息
        ‘‘‘

        # 验证逻辑
        if django not in value:
            # 失败
            raise serializers.ValidationError(btitle数据错误信息)

        # 成功
        return value

Shell测试代码:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {btitle: python}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{btitle: [ErrorDetail(string=btitle数据错误信息, code=invalid)]}
>>> data = {btitle: python_django}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([(btitle, python_django)])

3.4 对所有字段进行扩展验证

我们需要在序列化器中定义一个名字为(validate())的方法,来补充对所有字段进行扩展验证的逻辑。

def validate(self, attrs):
        ‘‘‘
        对多个字段进行验证
        :param attrs: 前段传递的字典数据
        :return: 验证成功:返回attrs;验证失败:返回错误信息
        ‘‘‘

同样,我们也需要使用raise抛出异常信息。

例如:

def validate(self, attrs):
        ‘‘‘
        对多个字段进行验证
        :param attrs: 前段传递的字典数据
        :return: 验证成功:返回attrs;验证失败:返回错误信息
        ‘‘‘

        # 验证逻辑:这里需要验证的是bread大于bcomment
        bread = attrs.get(bread)
        bcomment = attrs.get(bcomment)

        if bread < bcomment:
            # 失败
            raise serializers.ValidationError(bread需要大于bcomment)

        # 成功
        return attrs

Shell测试代码:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {btitle: about django, bread: 10, bcomment: 20}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{non_field_errors: [ErrorDetail(string=bread需要大于bcomment, code=invalid)]}
>>> data = {btitle: about django, bread: 50, bcomment: 20}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([(btitle, about django), (bread, 50), (bcomment, 20)])

4. 验证后的字典数据 ---> 模型数据

这里,我们已将到了数据反序列化的最后一步操作了。

同样,我们也应该知道,将验证后的字典数据转模型数据的实质,其实就是将验证过的字典数据添加到数据库中。

那么,对于将数据保存到数据库中的操作一共就两种:一种是添加数据的操作,一种是修改数据的操作。

4.1 添加数据

我们,想要添加数据,就需要在序列化器类中定义一个create()方法。

def create(self, validated_data):
        ‘‘‘
        序列化器进行新增数据的方法
        :param validated_data: 通过验证的字典数据
        :return:根据RESTful设计方式,需要将添加的数据返回
        ‘‘‘
        
        return ORM添加数据的语句(模型类.objects.create(**validated_data))

例如:

def create(self, validated_data):
        ‘‘‘
        序列化器进行新增数据的方法
        :param validated_data: 通过验证的字典数据
        :return:根据RESTful设计方式,需要将添加的数据返回
        ‘‘‘

        return BookInfo.objects.create(**validated_data)

在这里,我们需要返回添加的数据给前端,因为我们定义的API是遵守RESTful设计风格的。

Shell测试代码:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {btitle: django手册, bpub_date: 2020-02-05, bread: 20, bcomment: 10}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.save()
<BookInfo: django手册>

注意:

当我们创建序列化对象时,只传递data数据,就表示我们需要向数据库里添加数据

所以,当序列化器对象调用save()方法时,会自动调用序列化器类中的create()方法

4.2 修改数据

我们,想要修改数据时,需要在序列化器类中定义一个update()方法。

    def update(self, instance, validated_data):
        ‘‘‘
        序列化器进行修改数据的方法
        :param instance: 需要修改的模型对象
        :param validated_data: 前端传递的字典数据
        :return: 根据RESTful设计方式,需要将修改的数据返回
        ‘‘‘
        
        # 新值覆盖旧值
        instance.字段名 = validated_data.get(字段名)
        instance.save()
        return instance

例如:

def update(self, instance, validated_data):
        ‘‘‘
        序列化器进行修改数据的方法
        :param instance: 需要修改的模型对象
        :param validated_data: 前端传递的字典数据
        :return: 根据RESTful设计方式,需要将修改的数据返回
        ‘‘‘

        # 新值覆盖旧值
        instance.btitle = validated_data.get(btitle)
        instance.bpub_date = validated_data.get(bpub_date)
        instance.bread = validated_data.get(bread)
        instance.bcomment = validated_data.get(bcomment)
        instance.save()

        return instance

我们同样也需要将修改的数据返回给前端。

Shell测试代码:

from booktest.models import BookInfo
from booktest.serializers import BookInfoSerializer
>>> book = BookInfo.objects.get(id=10)
>>> data = {btitle: python_django手册, bpub_date: 2020-02-05, bread: 20, bcomment: 10}
>>> s = BookInfoSerializer(instance=book,data=data)
>>> s.is_valid()
True
>>> s.save()
<BookInfo: python_django手册>

注意:

当我们创建序列化器对象时,传递了instancedata数据,就表示我们需要进行数据的修改操作。

所以,当我们使用序列化器对象调用save()方法时,会自动调用序列化器类中的update()方法。

至此,我们的Serializer序列化的反序列化操作就学习完毕了。

序列化器的学习中,几乎没有什么逻辑点,因为,使用的是他人已经封装好的框架,所以必须遵守框架的规定来开发,只需要,记住模版即可。

DRF框架之Serializer序列化器的反序列化操作

原文:https://www.cnblogs.com/chao666/p/12269977.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!