DRF 序列化器-Serializer (2)
作用
1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
2. 完成数据校验功能
3. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
准备数据模型类booktest/model.py
class BookInfoSerializer(serializers.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)
image = serializers.ImageField(label='图片', required=False)
一 定义序列化器
Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer。
我们为模型类提供一个序列化器.
class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label='ID', read_only=True) #read_only 仅仅用于读取数据
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)
image = serializers.ImageField(label='图片', required=False)
注意:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。
二 查询库表
常见字段类型
| 字段 | 字段构造方式 |
|---|---|
| BooleanField | BooleanField() |
| NullBooleanField | NullBooleanField() |
| CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
| EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
| RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
| SlugField | SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+ |
| URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
| UUIDField | UUIDField(format='hex_verbose') format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" |
| IPAddressField | IPAddressField(protocol='both', unpack_ipv4=False, **options) |
| IntegerField | IntegerField(max_value=None, min_value=None) |
| FloatField | FloatField(max_value=None, min_value=None) |
| DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
| DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
| DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
| TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
| DurationField | DurationField() |
| ChoiceField | ChoiceField(choices) choices与Django的用法相同 |
| MultipleChoiceField | MultipleChoiceField(choices) |
| FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ListField | ListField(child=, min_length=None, max_length=None) |
| DictField | DictField(child=) |
选项参数
| 参数名称 | 作用 |
|---|---|
| max_length | 最大长度 |
| min_lenght | 最小长度 |
| allow_blank | 是否允许为空 |
| trim_whitespace | 是否截断空白字符 |
| max_value | 最小值 |
| min_value | 最大值 |
通用参数
| 参数名称 | 说明 |
|---|---|
| read_only | 表明该字段仅用于序列化输出,默认False |
| write_only | 表明该字段仅用于反序列化输入,默认False |
| required | 表明该字段在反序列化时必须输入,默认True |
| default | 反序列化时使用的默认值 |
| allow_null | 表明该字段是否允许传入None,默认False |
| validators | 该字段使用的验证器 |
| error_messages | 包含错误编号与错误信息的字典 |
| label | 用于HTML展示API页面时,显示的字段名称 |
| help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
三 创建Serializer对象
定义好Serializer类后,就可以创建Serializer对象了.
Serializer(instance=None, data=empty, **kwarg)
创建序列化器对象
- 参数1: instance=要序列化的模型数据
- 参数2: data=要反序列化器的字典数据
- 参数3: many= 是否要序列化多个模型数据,多条数据many=True,默认一条数据
- 参数4: context=序列化器使用的上下文,字典类型数据,可以通过context把视图中的数据,传递给序列化器内部使用
说明:
1)用于序列化时,将模型类对象传入instance参数
2)用于反序列化时,将要被反序列化的数据传入data参数
3)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如
serializer = AccountSerializer(account, context={
'request': request
}) #把数据传递给序列器
通过context参数附加的数据,可以通过Serializer对象的context属性获取。
四 序列化器的使用
序列化器的使用分两个阶段:
在客户端请求时,使用序列化器可以完成对数据的反序列化。
在服务器响应时,使用序列化器可以完成对数据的序列化。
五 序列化
三步骤:
1 操作数据库
2 构造序列化器对象
3 响应数据
class BookInfoView(View):
def get(self,request):
# 操作数据库
books = BookInfo.objects.all()
# 创建序列化器对象
serializer = BookInfo2Serializer(instance=books,many=True)
# 通过 serializer.data 获取序列化完成以后的数据
print ( serializer.data )
# 返回数据
return JsonResponse(serializer.data,safe=False) #safe=Fase 表示跳过严格检验数据类型是否为dict
如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明
book_qs = BookInfo.objects.all()
serializer = BookInfoSerializer(book_qs, many=True)
serializer.data
# [OrderedDict([('id', 2), ('btitle', '天龙八部'),
('bpub_date', '1986-07-24'), ('bread', 36), ('bcomment', 40),
('image', N]), OrderedDict([('id', 3), ('btitle', '笑傲江湖'),
('bpub_date', '1995-12-24'), ('bread', 20), ('bcomment', 80),
('image'ne)]), OrderedDict([('id', 4), ('btitle', '雪山飞狐'),
('bpub_date', '1987-11-11'), ('bread', 58), ('bcomment', 24),
('ima None)]), OrderedDict([('id', 5), ('btitle', '西游记'),
('bpub_date', '1988-01-01'), ('bread', 10), ('bcomment', 10),
('im', 'booktest/xiyouji.png')])]
六 反序列化
(1)数据验证
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
- 数据校验的序列器的编写(字段中编写校验规则)
class BookInfo2Serializer(serializers.Serializer):
# 自定义要反序列化的字段
id = serializers.IntegerField(label="主键ID",read_only=True)
btitle = serializers.CharField(label="标题",required=True,min_length=1,max_length=20,validators=[check_btitle])
bpub_date=serializers.DateField(label="出版日期")
bread=serializers.IntegerField(label="阅读量",min_value=0)
bcomment=serializers.IntegerField(label="评论量",default=0)
# required=False 反序列化时, 当前字段可以不填
is_delete=serializers.BooleanField(label="逻辑删除")
- 自定义验证方法
def validate_btitle(self,data):
# 例如,图书名不能是红楼梦
if data=="红楼梦":
# 抛出错误
raise serializers.ValidationError("红楼梦是禁书~")
# 验证方法中,把数据值必须返回给字段,否则字段值为空
return data
# 自定义验证方法[验证多个或者所有字段,只能出现一次]
def validate(self,data): # data 这个是所有字段的内容,字典类型
bread = data.get("bread")
bcomment = data.get("bcomment") if bread>=bcomment:
return data
raise serializers.ValidationError("阅读量小于评论量,数据太假了")
def create(self,validated_data):
"""保存数据,把字典转换成模型
validated_data 客户端提交过来,并经过验证的数据
"""
instance = BookInfo.objects.create(
btitle = validated_data.get("btitle"),
bread = validated_data.get("bread"),
bcomment = validated_data.get("bcomment"),
bpub_date = validated_data.get("bpub_date"),
is_delete = validated_data.get("is_delete"),
)
注意:
1 验证单个字段,可以有多个方法
2 def validate_<字段名>(self,data): # data当前字段对应的值
3 验证多个或者所有字段,只能出现一次
(2)反序列化-数据保存view视图
前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象.
from django.views import View
from django.http import QueryDict
from .serializers import BookInfo2Serializer
class BookInfo2View(View):
def post(self,request):
"""添加一本图书"""
# 接受数据
data = request.POST
# 反序列化
serializer = BookInfo2Serializer(data=data)
# 1. 验证数据
# raise_exception=True 把验证的错误信息返回给客户端,同时阻止程序继续往下执行
serializer.is_valid(raise_exception=True)
# is_valid调用验证方式: 字段选项validators->自定义验证方法[单字段]->自定义验证方法[多字段]
# 验证成功后的数据
# print(serializer.validated_data)
# 2. 转换数据成模型,同步到数据库中
result = serializer.save() # save会自动调用序列化器类里面声明的create/update方法,返回值是当前新增/更新的模型对象 # 响应数据
return JsonResponse(serializer.data) def put(self,request,pk):
"""更新一个图书"""
# 根据id主键获取指定图书信息
book = BookInfo.objects.get(pk=pk) # 获取put数据
data = QueryDict(request.body) # 使用序列化器完成验证和反序列化过程
# partial=False接下里在反序列化中允许部分数据更新
serializer = BookInfo2Serializer(instance=book,data=data,partial=False
) serializer.is_valid(raise_exception=True) serializer.save() # 响应数据 return JsonResponse(serializer.data)
注意:
save之所以可以自动识别,什么时候执行create ,什么时候执行update
主要是看创建序列化器对象时,是否有传入instance参数,
有instance参数,则save会调用序列化器内部的update方法
没有instance参数,则save会调用序列化器内部的create方法
七 超级版序列化器(ModelSerializer)
serializers.py
from rest_framework import serializers
from booktest.models import BookInfo
class BookInfoModelSerializer(serializers.ModelSerializer):
# 模型序列化器也可以自定义验证字段[当某些数据不存在于数据库时,但是需要前端提交过来的,可以进行自定义,
# 例如,验证码,确认密码] class Meta:
model=BookInfo
fields = ["id","btitle"]
# 可以给模型序列化器里面指定的字段设置限制选项
extra_kwargs = {
"bread":{"min_length":0,"required":True},
} # 自定义验证方法[验证单个字段,可以有多个方法]
# def validate_<字段名>(self,data): # data当前字段对应的值
def validate_btitle(self,data):
# 例如,图书名不能是红楼梦
if data=="红楼梦":
# 抛出错误
raise serializers.ValidationError("红楼梦是禁书~")
# 验证方法中,把数据值必须返回给字段,否则字段值为空
return data # 自定义验证方法[验证多个或者所有字段,只能出现一次]
def validate(self,data): # data 这个是所有字段的内容,字典类型
bread = data.get("bread")
bcomment = data.get("bcomment") if bread>=bcomment:
return data
raise serializers.ValidationError("阅读量小于评论量,数据太假了")
views.py
###############################################################################################################################
# 3 模型序列化器
# 1. 可以帮我们自动完成字段的声明[主要是从模型中的字段声明里面提取过来]
# 2. 模型序列化器也可以帮我们声明了create和update方法的代码
###############################################################################################################################
from django.views import View
from django.http import JsonResponse
from .serializers import BookInfoModelSerializer
class BookInfo3View(View):
def post(self,request):
"""添加一本图书"""
# 接受数据
data = request.POST
# 反序列化
serializer = BookInfoModelSerializer(data=data)
serializer.is_valid(raise_exception=True)
result = serializer.save()
# 响应数据
return JsonResponse(serializer.data) def put(self,request,pk):
"""更新一个图书"""
book = BookInfo.objects.get(pk=pk) # 获取put提交的数据
data = QueryDict(request.body) serializer = BookInfoModelSerializer(instance=book,data=data,partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
# 响应数据
return JsonResponse(serializer.data)
DRF 序列化器-Serializer (2)的更多相关文章
- 066.Python框架DRF之序列化器Serializer
一 序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成 ...
- DRF序列化器
序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成字典 ...
- Cf序列化器-Serializer解析
Cf序列化器-Serializer 定义序列化器 Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Seri ...
- day82 序列化器-Serializer
目录 一.序列化器的基本功能 二.定义序列化器 三.创建Serializers对象 四.序列化器的使用 1 序列化 2 反序列化 2.1 数据验证(类比forms组件) 2.2 数据保存 一.序列化器 ...
- drf序列化器serializers.SerializerMethodField()的用法
问题描述: 为什么DRF中有时候返回的json中图片是带域名的,有时候是不带域名的呢? 解析: 带域名的结果是在view中对模型类序列化的,DRF在序列化图片的时候 会检查上下文有没有request, ...
- drf序列化器的实例
应用目录结构: views.py from django.shortcuts import render # Create your views here. from django.views imp ...
- DRF序列化器的使用
序列化器的使用 序列化器的使用分两个阶段: 在客户端请求时,使用序列化器可以完成对数据的反序列化. 在服务器响应时,使用序列化器可以完成对数据的序列化. 序列化的基本使用 使用的还是上一篇博文中使用的 ...
- drf序列化器与反序列化
什么是序列化与反序列化 """ 序列化:对象转换为字符串用于传输 反序列化:字符串转换为对象用于使用 """ drf序列化与反序列化 &qu ...
- 4)drf序列化组件 Serializer(偏底层)、ModelSerializer(重点)、ListModelSerializer(辅助群改)
知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 一.Serializer 偏底层 一般不用 理解原理 1.序列化准备 ...
随机推荐
- .NET Core中的数据保护组件
原文地址: PREVENTING INSECURE OBJECT REFERENCES IN ASP.NET CORE 2.0 作者: Tahir Naushad 背景介绍 在 OWASP(开放式 W ...
- redis 系列26 Cluster高可用 (1)
一.概述 Redis集群提供了分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能.在大数据量方面的高可用方案,cluster集群比Sentinel有优势.但Redis集群并不支持处 ...
- javascript深入理解js闭包(转载)
此篇文章来源于http://www.jb51.net/article/24101.htm 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全 ...
- 带着新人学springboot的应用12(springboot+Dubbo+Zookeeper 下)
上半节已经下载好了Zookeeper,以及新建了两个应用provider和consumer,这一节我们就结合dubbo来测试一下分布式可不可以用. 现在就来简单用一下,注意:这里只是涉及最简单的部分, ...
- Java IO模型
Linux的内核将所有外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符).而对一个Socket的读写也会有相应的描述 ...
- HBase Region合并分析
1.概述 HBase中表的基本单位是Region,日常在调用HBase API操作一个表时,交互的数据也会以Region的形式进行呈现.一个表可以有若干个Region,今天笔者就来和大家分享一下Reg ...
- REST API设计指导——译自Microsoft REST API Guidelines(二)
由于文章内容较长,只能拆开发布.翻译的不对之处,请多多指教. 另外:最近团队在做一些技术何架构的研究,视频教程只能争取周末多录制一点,同时预计在下周我们会展开一次直播活动,内容围绕容器技术这块. 所有 ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
- Python迭代和解析(2):迭代初探
解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 在Python中支持两种循环格式:while和for.这两种循环的类型不 ...
- Docker多主机管理(八)--技术流ken
docker多主机管理 前面我们的实验环境中只有一个 docker host,所有的容器都是运行在这一个 host 上的.但在真正的环境中会有多个 host,容器在这些 host 中启动.运行.停止和 ...