昨天,我们完成了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序列化器的反序列化操作的更多相关文章

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

    在DRF框架中,有两种序列化器,一种是Serializer,另一种是ModelSerializer. 今天,我们就先来学习一下Serializer序列化器. 使用Serializer序列化器的开发步骤 ...

  2. 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用

    写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...

  3. DRF框架之ModelSerializer序列化器

    ModelSerializer是Serializer的子类,序列化和反序列化跟Serializer一样. ModelSerializer与常规的Serializer相同,但提供了: 基于模型类自动生成 ...

  4. 一: DRF web应用框架基础,及序列化器的使用

    ---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...

  5. DRF框架之 serializers 序列化组件

    1. 什么是序列化,其实在python中我们就学了序列化工具json工具,就是吧信息存为类字典形式 2. DRF框架自带序列化的工具: serializers 3. DRF框架 serializers ...

  6. drf序列化器与反序列化

    什么是序列化与反序列化 """ 序列化:对象转换为字符串用于传输 反序列化:字符串转换为对象用于使用 """ drf序列化与反序列化 &qu ...

  7. 【DRF框架】利用序列化组件操作

    使用序列化组件进行操作 不带参数:查+增 带参数:查.改.删 不带参数的操作 # url路由 url(r'^book_list/$',Search_book.as_view()), # views.p ...

  8. DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)

    解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...

  9. 066.Python框架DRF之序列化器Serializer

    一 序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成 ...

随机推荐

  1. 百度DMA+小度App的蓝牙语音解决方案技术难点解析

    前记   你平时在商场看到的语音助手,看起来非常的简单,其实,这个小小语音助手的背后,是一个非常的复杂的技术支撑.从前端到后端的技术依次是:前端语音降噪技术,高效的音频编解码技术,蓝牙双模技术,DMA ...

  2. P3225 [HNOI2012]矿场搭建 题解

    这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的) 传送门   https://www.luogu.org/problem/P3225 省选oi题 ...

  3. 016 Ceph的集群管理_2

    一.Ceph集群的运行状态 集群状态:HEALTH_OK,HEALTH_WARN,HEALTH_ERR 1.1 常用查寻状态指令 [root@ceph2 ~]#    ceph health deta ...

  4. alpha week 2/2 Scrum立会报告+燃尽图 06

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/9803 小组名称:“组长”组 组长:杨天宇 组员:魏新,罗杨美慧,王歆瑶, ...

  5. fastdfs基本安装流程和集成springboot总结

    FastDFS介绍 1.简介 FastDFS 是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡.主要解决了海量数据存储问题,特别适合以 ...

  6. 07Shell数组

    Shell 数组变量 普通数组:只能使用整数作为数组索引 关联数组:可以使用字符串作为数组索引 普通数组 定义数组 方法1: 一次赋一个值 数组名[索引]=变量值 示例 # array1[0]=pea ...

  7. 「洛谷P1306」斐波那契公约数 解题报告

    P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很"简单"问题:第n项和第m项的最大公 ...

  8. 「2018-11-05模拟赛」T5 传送机 解题报告

    5.传送机(sent.*) 问题描述: 黄黄同学要到清华大学上学去了.黄黄同学很喜欢清华大学的校园,每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄黄同学想每条路也只走一遍. 我们一般人很可能对 ...

  9. 软考网络工程师、软件设计师等官方指定教材pdf文件

    软考计算机网络工程师教材pdf 链接:https://pan.baidu.com/s/1-UXeNye414UWYxYRC6bHuA 提取码:5z9w 软考计算机软件设计师第五版pdf 链接:http ...

  10. 深入理解linux i节点(inode)

    转载自:https://blog.csdn.net/vsooda/article/details/9216245 linux中,文件查找不是通过文件名称来查找的.实际上是通过i节点来实现文件的查找定位 ...