django 学习之DRF (二)
Django学习之DRF02
Serializer序列化器之反序列化操作
1.调⽤序列化器进⾏验证
0.准备序列化器
class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label= 'ID', read_only= True)
btitle = serializers.CharField(label= )
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)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True)
1.验证失败的情况
>>> from booktest.serializers import BookInfoSerializer
>>> data = {}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'btitle': [ErrorDetail(string='This field is required.', code='required')]}
2.验证成功的情况
>>> data = {'btitle':'⽔浒传'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([('btitle', '⽔浒传')])
3.验证同时抛异常
>>> data = {}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid(raise_exception=True)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/zhangjie/.virtualenvs/ py3_django/lib/python3.6/site-packages/rest_framework/serializers.py", line 244, in is_valid
raise ValidationError(self.errors)
rest_framework.exceptions.ValidationError: {'btitle': [ErrorDetail(string='This field is required.', code='required')]}
2.定义序列化器进⾏验证
1.单个字段验证
1.准备序列化器
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)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
def validate_btitle( self, value):
"""单个字段验证"""
if ' django' not in value.lower():
raise serializers.ValidationError(" 图书不是关于Django的 " )
return value
2.验证
>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle':'python'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'btitle': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
2.多字段联合验证
1.提示 多字段联合验证是在单个字段验证之后进⾏的验证
2.准备序列化器
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)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
def validate_btitle( self, value):
"""单个字段验证"""
if ' django' not in value.lower():
raise serializers.ValidationError(" 图书不是关于Django的 " )
return value
def validate(self, attrs):
"""多字段联合验证"""
bread = attrs[ 'bread']
bcomment = attrs[ ' bcomment' ]
if bread < bcomment:
raise serializers.ValidationError(' 阅读量⼩于评论量' )
return attrs
3.验证
为了让单个字段验证成功,btitle设置为django
>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle':'django', 'bread':10, 'bcomment':20}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'non_field_errors': [ErrorDetail(string='阅读量⼩于评论量', code='invalid')]}
>>>
'non_field_errors' 多字段联合校验时的错误信息key
3. validators
def about_django(value):
if ' django' not in value.lower():
raise serializers.ValidationError(" 图书不是关于Django的 " )
1.准备序列化器
class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label= 'ID', read_only= True)
btitle = serializers.CharField(label= ' 名称' , max_length= 20, validators=[about_django])
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)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True)
2.验证
>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle':'python'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'btitle': [ErrorDetail(string='图书不是关于Django的', code='invalid')]}
>>>
3.保存序列化器验证后的数据
1.准备序列化器
class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label= 'ID', read_only= True)
btitle = serializers.CharField(label= ' 名称' , max_length= 20, validators=[about_django])
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)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only= True, many= True) # 新增
def validate_btitle( self, value):
"""单个字段验证"""
if ' django' not in value.lower():
raise serializers.ValidationError(" 图书不是关于Django的 " )
return value
def validate(self, attrs):
"""多字段联合验证"""
bread = attrs[ 'bread']
bcomment = attrs[ ' bcomment' ]
if bread < bcomment:
raise serializers.ValidationError(' 阅读量⼩于评论量' )
return attrs
def create(self, validated_data):
"""新建"""
return BookInfo.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.btitle = validated_data.get(' btitle' , instance.btitle)
instance.bpub_date = validated_data.get(' bpub_date' , instance.bpub_date)
instance.bread = validated_data.get('bread', instance.bread)
instance.bcomment = validated_data.get(' bcomment' , instance.bcomment)
instance.save()
return instance
2.验证后保存
说明:
data中的数据,要让验证通过
没有传⼊模型对象实例,所以是新增数据
>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle':'django', 'bread':30, 'bcomment':10, 'bpub_date':'1989-11-11'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> book = s.save()
>>> book
<BookInfo: django>
3.验证后更新
>>> data = {'btitle':'django python', 'bread':30, 'bcomment':10, 'bpub_date':'1989-11-11'}
>>> s = BookInfoSerializer(book, data=data)
>>> s.is_valid()
True
>>> s.save()
<BookInfo: django python>
模型类序列化器ModelSerializer
1.模型类字段全部映射到序列化器
1.准备序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
"""BookInfo模型类的序列化器"""
class Meta:
model = BookInfo
fields = '__all__'
2.创建序列化器对象
>>> from booktest.serializers import BookInfoModelSerializer
>>> s = BookInfoModelSerializer()
>>> s
BookInfoModelSerializer():
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名称', max_length=20)
bpub_date = DateField(label='发布⽇期')
bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
is_delete = BooleanField(label='逻辑删除', required=False)
image = ImageField(allow_null=True, label='图书图⽚', max_length=100, required=False)
2.模型类字段部分映射到序列化器
1.准备序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
"""BookInfo模型类的序列化器"""
class Meta:
model = BookInfo
# fields = '__all__'
fields = ['id', ' btitle' , ' bpub_date' ]
2.创建序列化器对象
>>> from booktest.serializers import BookInfoModelSerializer
>>> s = BookInfoModelSerializer()
>>> s
BookInfoModelSerializer():
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名称', max_length=20)
bpub_date = DateField(label='发布⽇期')
3.模型类字段排除指定字段
1.准备序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
"""BookInfo模型类的序列化器"""
class Meta:
model = BookInfo
exclude = ('image',)
2.创建序列化器对象
>>> from booktest.serializers import BookInfoModelSerializer
>>> s = BookInfoModelSerializer()
>>> s
BookInfoModelSerializer():
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名称', max_length=20)
bpub_date = DateField(label='发布⽇期')
bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
is_delete = BooleanField(label='逻辑删除', required=False)
4.嵌套
1.准备序列化器
class HeroInfoModelSerializer(serializers.ModelSerializer):
class Meta:
model = HeroInfo
fields = ['id', ' hname' , ' hbook' ]
depth = 1 # 嵌套深度
2.创建序列化器对象
>>> from booktest.serializers import HeroInfoModelSerializer
>>> s = HeroInfoModelSerializer()
>>> s
HeroInfoModelSerializer():
id = IntegerField(label='ID', read_only=True)
hname = CharField(label='名称', max_length=20)
hbook = NestedSerializer(read_only=True):
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名称', max_length=20)
bpub_date = DateField(label='发布⽇期')
bread = IntegerField(label='阅读量', max_value=2147483647, min_value=-2147483648, required=False)
bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=-2147483648, required=False)
is_delete = BooleanField(label='逻辑删除', required=False)
image = ImageField(allow_null=True, label='图书图⽚', max_length=100, required=False)
5.指明只读字段
class BookInfoModelSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo
fields = ('id', ' btitle' , ' bpub_date' , 'bread', ' bcomment' )
read_only_fields = ('id', 'bread', ' bcomment' )
6.添加额外参数
1.准备序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
"""BookInfo模型类的序列化器"""
class Meta:
model = BookInfo
fields = ('id', ' btitle' , ' bpub_date' , 'bread', ' bcomment' )
extra_kwargs = {
'bread': {'min_value': 0 , 'required': True},
' bcomment' : {'min_value': 0 , 'required': True},
}
2.创建序列化器对象
>>> from booktest.serializers import BookInfoModelSerializer
>>> s = BookInfoModelSerializer()
>>> s
BookInfoModelSerializer():
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名称', max_length=20)
bpub_date = DateField(label='发布⽇期')
bread = IntegerField(label='阅读量', max_value=2147483647, min_value=0, required=True)
bcomment = IntegerField(label='评论量', max_value=2147483647, min_value=0, required=True)
视图
1.Request和Response
1.Request
1.介绍 Request对象的数据是⾃动根据前端发送数据的格式进⾏解析之后的结果。
2.属性
1 ) .data
request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和 request.FILES属性,但提供如下特性:
• 包含了解析之后的⽂件和⾮⽂件数据
• 包含了对POST、 PUT、 PATCH请求⽅式解析后的数据
• 利⽤了REST framework的 parsers解析器,不仅⽀持表单类型数据,也⽀持JSON数据
2 ) .query_params
request.query_params与 Django标准的request.GET相同,只是更换了更正确的名称⽽已。
2.Response
1.介绍
rest_framework.response.Response
REST framework提供了⼀个响应类Response,使⽤该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
2.渲染器
REST framework提供了Renderer 渲染器,⽤来根据请求头中的Accept(接收数据类型声明)来⾃动转换响应数据到对应格式。
如果前端请求中未进⾏Accept声明,则会采⽤默认⽅式处理响应数据,我们可以通过配置来修改默认响应格式。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
)
}
3.构造⽅法
Response(data, status=None, template_name=None, headers=None, content_type=None)
参数说明:
• data: 为响应准备的序列化处理后的数据;
• status: 状态码,默认200;
• template_name: 模板名称,如果使⽤HTMLRenderer 时需指明;
• headers: ⽤于存放响应头信息的字典;
• content_type: 响应数据的Content-Type,通常此参数⽆需传递,REST framework会根据前端所需类型数据来设置该参数。
4.属性
1 ) .data
传给response对象的序列化后,但尚未render处理的数据
2 ) .status_code
状态码的数字
3 ) .content
经过render处理后的响应数据
5.状态码
为了⽅便设置状态码,REST framewrok在 rest_framework.status模块中提供了常⽤状态码常量。
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
......
2.DRF中类视图概览
3.使⽤APIView基类视图
1.APIView基类视图介绍
2.需求 使⽤APIView实现“获取所有图书信息”接⼝
3.后端接⼝定义
1.视图
class BookListView(APIView):
def get(self, request):
"""
GET /books/
:param request: Request类型的对象
:return: JSON
"""
pass
2.路由 # 演示APIView,实现获取所有图书信息接⼝
url(r'^books/$', views.BookListView.as_view()),
4.后端接⼝实现
1.视图
class BookListView(APIView):
def get(self, request):
"""
GET /books/
:param request: Request类型的对象
:return: JSON
"""
# 查询数据库
qs = BookInfo.objects.all()
# 实现序列化
serializer = BookInfoSerializer(qs, many= True)
# 响应序列化结果
return Response(serializer.data)
2.序列化器
可使⽤之前定义过的序列化器
class BookInfoSerializer(serializers.Serializer):
pass
class BookInfoModelSerializer(serializers.ModelSerializer):
pass
4.使⽤GenericAPIView基类视图
1.GenericAPIView基类视图介绍
2.需求
1.使⽤GenericAPIView实现“获取所有图书信息”接⼝
2.使⽤GenericAPIView实现“获取单⼀图书信息”接⼝
3.实现“获取所有图书信息”接⼝
1.视图
class BookListView(GenericAPIView):
# 指定查询集
queryset = BookInfo.objects.all()
# 指定序列化器
serializer_class = BookInfoSerializer
def get(self, request):
"""
GET /books/
:param request: Request类型的对象
:return: JSON
"""
# 查询数据库
qs = self.get_queryset()
# 实现序列化
serializer = self.get_serializer(qs, many= True)
# 响应序列化结果
return Response(serializer.data)
2.序列化器
可使⽤之前定义过的序列化器
class BookInfoSerializer(serializers.Serializer):
pass
class BookInfoModelSerializer(serializers.ModelSerializer):
pass
3.路由 # 演示APIView,GenericAPIView实现获取所有图书信息接⼝
url(r'^books/$', views.BookListView.as_view()),
4.实现“获取单⼀图书信息”接⼝
1.视图
class BookDetailView(GenericAPIView):
# 指定查询集
queryset = BookInfo.objects.all()
# 指定序列化器
serializer_class = BookInfoSerializer
def get(self, request, pk):
"""
GET /books/<pk>/
:param request: Request类型的对象
:param pk: 要访问的数据库记录
:return: JSON
"""
# 查询数据库:默认根据pk查询数据库单⼀结果
book = self.get_object()
# 实现序列化
serializer = self.get_serializer(book)
# 响应序列化结果
return Response(serializer.data)
2.序列化器
可使⽤之前定义过的序列化器
class BookInfoSerializer(serializers.Serializer):
pass
class BookInfoModelSerializer(serializers.ModelSerializer):
pass
3.路由 # 演示GenericAPIView,实现获取单⼀图书信息接⼝
url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
5.使⽤Mixin扩展类
1.Mixin扩展类介绍
2.需求 使⽤mixins扩展类搭配GenericAPIView基类视图,实现“获取所有图书信息”接⼝
3.实现
class BookListView(mixins.ListModelMixin, GenericAPIView):
# 指定查询集
queryset = BookInfo.objects.all()
# 指定序列化器
serializer_class = BookInfoSerializer
def get(self, request):
"""
GET /books/
:param request: Request类型的对象
:return: JSON
"""
return self.list(request)
6.使⽤GenericAPIView的⼦类视图
1.⼦类视图介绍
2.需求 使⽤使⽤GenericAPIView的⼦类视图, 实现“获取所有图书信息”接⼝
3.实现
# GET /books/
class BookListView(ListAPIView):
# 指定查询集
queryset = BookInfo.objects.all()
# 指定序列化器
serializer_class = BookInfoSerializer
相关源码连接:
django 学习之DRF (二)的更多相关文章
- Django学习笔记(二):使用Template让HTML、CSS参与网页建立
Django学习笔记(二):使用Template让HTML.CSS参与网页建立 通过本文章实现: 了解Django中Template的使用 让HTML.CSS等参与网页建立 利用静态文件应用网页样式 ...
- django 学习之DRF (三)
Django学习之DRF-03 视图集 1.视图集介绍 2.视图集基本使⽤ 1.需求 使⽤视图集获取列表数据和单⼀数据 2.实现 class BookInfoV ...
- Django 学习笔记(二)
Django 第一个 Hello World 项目 经过上一篇的安装,我们已经拥有了Django 框架 1.选择项目默认存放的地址 默认地址是C:\Users\Lee,也就是进入cmd控制台的地址,创 ...
- django 学习之DRF (一)
Django框架基础DRF-01 前后端分离介绍 1.前后端不分离图解 2.前后端分离图解 3.为什么要学习DRF DRF可以帮助我们开发者快速的开发⼀个依托于Django的前后后端分离 ...
- Django学习笔记之二
一.使用Django自带的后端管理平台 1.后台创建管理员 python manage.py createsuperuser Email address: admin@example.com Pass ...
- Django学习笔记(二)视图函数
一.url映射 1.为什么回去urls.py文件中找映射? 在‘settings.py’文件中配置了‘ROOT_URLCONF’为‘urls.py’.所有的django回去urls.py中寻找. 2. ...
- Django 学习笔记(二) --- HTML 模版
人生苦短 ~ Tips:仅适用于 Python 3+(反正差别不大,py2 改改也能用).因为据 Python 之父 Guido van Rossum 说会在 2020 年停止对 Python 2 的 ...
- django学习笔记(二)
上节内容回顾: 1.Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串 -> URL对应关系(匹配) -> 视图函数 -> ...
- python Django 学习笔记(二)—— 一个简单的网页
1,创建一个django项目 使用django-admin.py startproject MyDjangoSite 参考这里 2,建立视图 from django.http import HttpR ...
随机推荐
- UML解析
1.1 UML基础知识扫盲 UML这三个字母的全称是Unified Modeling Language,直接翻译就是统一建模语言,简单地说就是一种有特殊用途的语言. 你可能会问:这明明是一种图形,为什 ...
- [转] 张凌 ARM体系架构
很多时候我们都会对M0,M0+,M3,M4,M7,arm7,arm9,CORTEX-A系列,或者说AVR,51,PIC等,一头雾水,只知道是架构,不知道具体是什么,有哪些不同?今天查了些资料,来解解惑 ...
- tree指令
tree 中文解释:tree功能说明:以树状图列出目录的内容.语 法:tree [-aACdDfFgilnNpqstux][-I <范本样式>][-P <范本样式>][目录.. ...
- L2-013. 红色警报(dfs)
L2-013. 红色警报 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 战争中保持各个城市间的连通性非常重要.本题要求你编写一 ...
- 人脸识别FaceNet+TensorFlow
一.本文目标 利用facenet源码实现从摄像头读取视频,实时检测并识别视频中的人脸.换句话说:把facenet源码中contributed目录下的real_time_face_recognition ...
- highcharts图表的图例legend
一.将图例Legend放于图表右侧1.设置chart的marginRight属性值:chart: { marginRight: 120}2.设置legend图例属性值如下 legend: { alig ...
- 10-19C#基础--第四部分类型(2)重点
类型: 一.数字:Math类型 1)Math.Ceiling() ( 表示进位.));//只要小数点后有值,就向前进一位,取上限. string s = Console.ReadLine(); dou ...
- ABP缓存
简介 缓存是做什么的? 简单的可以认为是一个键值对的数据存于内存中,高速读取.作用为了减少和数据库的交互 Abp中缓存的使用 public class InvoiceAppService : Appl ...
- oracle常用函数总结(一)
最近在读数据库存储过程,或者在xml里写sql时用到数据库函数,笔者觉得有必要总结一下,当然有的函数笔者也很懵逼,不过可以问度娘啊!好了!开始正题. )s from dual;--1 若nvl第一个参 ...
- .net 4 安装未成功,无意中的解决办法!
公司 电脑是chost的系统,由于使用时间过长,重装纯净版系统的话,代价太大,故网上寻求各种解决办法! 安装.net 4 总是失败,查看百度,各种: WIN7系统哈哈跟我的问题一样,我的刚才解决了:1 ...