drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类
1.模块与包
# 模块与包
模块:一个py文件 被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件
包:一个文件夹下有__init__.py
# 模块与包的导入问题
'''
1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的
2.导入任何模块,如果使用绝对导入,都是从环境变量开始导起
3.脚本文件执行的路径,会自动加入环境变量
4.相对导入的话,是从当前py文件开始计算的
5.以脚本运行的文件,不能使用相对导入,只能用绝对导入
'''
2.反序列化校验源码分析(了解)
# 序列化类的校验功能
局部钩子:必须 validate_字段名
全局钩子:validate
# 入口
ser.is_valid 才做的校验---》入口
先从自己写的BookSerializer类中找is_valid方法----》再到继承的父类Serializer中找---》再到它的父类BaseSerializer中找----》is_valid---》还继承了Field
'''BookSerializer类中的is_valid方法'''
def is_valid(self, *, raise_exception=False):
# self中没有_validated_data,只有执行完后,才有(校验过后的数据)
if not hasattr(self, '_validated_data'):
try:
# 核心---》这一句
# 想看它的源代码,按住ctrl+鼠标点击是不对的---》只能找当前类的父类,要从根上开始找
self._validated_data = self.run_validation(self.initial_data)
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
if self._errors and raise_exception:
raise ValidationError(self.errors)
return not bool(self._errors)
"""
self.run_validation(self.initial_data)
在Serializer中有run_validation这个方法先执行这个
"""
def run_validation(self, data=empty):
# 局部钩子
value = self.to_internal_value(data)
try:
# 全局钩子
value = self.validate(value) # BookSerializer只要写了,优先执行它的
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
"""
局部钩子
self.to_internal_value(data)---》Serializer类的方法
"""
def to_internal_value(self, data):
for field in fields: #序列化类中写的一个个的字段类的对象列表
# 一个field是name对象,field.field_name字符串 name
# self是谁的对象:序列化类的对象,BookSerializer的对象 validate_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 字段自己的校验规则
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
# 局部钩子
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
# 总结
ser.is_valid--->走局部钩子的代码---》是通过反射获取BookSerializer中写的局部钩子函数,如果写了,就会执行---》走全局钩子代码---》self.validate(value)---》只要序列化类中写了,优先走自己的
3.断言
assert hasattr(self, 'initial_data'), (
'Cannot call `.is_valid()` as no `data=` keyword argument was '
'passed when instantiating the serializer instance.'
)
# 断言某个东西是我认为的,如果不是就抛异常
# 等同于if判断+抛异常
def add(a,b):
return a + b
res = add(8,9)
# assert res == 16,Exception('不等于16')
if not res == 16:
raise Exception('不等于16')
print('随便')
4.drf之请求
# 视图类:APIView
# 序列化组件:Serializer,ModelSerializer
# drf:Request类的对象
4.1Request类对象的分析
1.data
request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和request.FILES属性,但提供如下特性:
包含了解析之后的文件和非文件数据
包含了对POST、PUT、PATCH请求方式解析后的数据
利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
2..query_params
request.query_params等同于request.GET
3.其他的属性用法跟之前一样
4.2请求能够接受的编码格式
# urlencoded
# form-data
# json
三种都支持
可以限制只能接受某种或者某几种编码格式
# 限制方式一:在视图类上写--》只是局部视图类有效
# 总共有三个:JSONParser,FormParser, MultiPartParser
class BookView(APIView):
parser_classes = [JSONParser, FormParser]
# 限制方式二:在配置文件中写---》全局有效
# drf的配置(在rest_framework的setting中),统一写成它
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',
],
}
# 全局配置了只支持json,局部想支持3个
-只需要在局部,视图类中,写3个即可
class BookView(APIView):
parser_classes = [JSONParser, FormParser,MultiPartParser]
# 总结:能够处理的请求方式编码
-优先从视图类中找
-再去项目配置文件找
-再去drf默认的配置中找
5.drf之响应
5.1响应类的对象Response
# return Response({'code':100})
data:响应体的内容,可以字符串,字典,列表
status:http响应状态码
drf把所有响应码都定义成一个常量
template_name:模板名字,用浏览器访问,看到好看的页面,用postman访问,返回正常数据
-自定制页面
-根本不用
headers:响应头加数据(后面讲跨域问题再讲)
-headers={'name':'lqz'}
content_type:响应编码,一般不用
# 三个重要的:data,status,headers
5.2响应的格式
# 默认是两种:纯json,浏览器看到的样子
# 限制方式一:在视图类上写---》只是局部视图类有效
# 总共有两个:JSONRenderer,BrowsableAPIRenderer
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer]
# 限制方式二:在配置文件中写---》全局有效
# drf的配置,统一写成它
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
],
}
# 全局配置了只支持json,局部想支持2个
-只需要在局部,视图类中,写2个即可
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
6.视图之两个视图基类
# 视图类:
-APIView:之前用过
-GenericAPIView:GenericAPIView继承了APIView
# GenericAPIView
-类属性:
queryset:要序列化的所有数据
serializer_class:序列化类
lookup_field = 'pk' :查询单条时的key值
-方法:
-get_queryset():获取所有要序列化的数据【后期可以重写】
-get_serializer : 返回序列化类
-get_object :获取单个对象
#总结:以后继承GenericAPIView写接口
1 必须配置类属性
queryset
serializer_class
2 想获取要序列化的所有数据
get_queryset()
3 想使用序列化类:
get_serializer
4 想拿单条
get_object
6.1使用APIView+序列化类+Response写接口
from rest_framework.views import APIView
from .serializer import BookSerialzier
from rest_framework.response import Response
from .models import Book
# class BookView(APIView):
# def get(self, request):
# qs = Book.objects.all()
# ser = BookSerialzier(qs, many=True)
# return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
# def post(self, request):
# ser = BookSerialzier(data=request.data)
# if ser.is_valid():
# ser.save()
# return Response({'code': 100, 'msg': '成功'})
# else:
# return Response({'code': 100, 'msg': ser.errors})
#
#
# class BookDetailView(APIView):
# def get(self, request, pk):
# book = Book.objects.all().get(pk=pk)
# ser = BookSerialzier(book)
# return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
# def put(self, request, pk):
# book = Book.objects.get(pk=pk)
# ser = BookSerialzier(data=request.data, instance=book)
# if ser.is_valid():
# ser.save()
# return Response({'code': 100, 'msg': '更新成功'})
# else:
# return Response({'code': 100, 'msg': ser.errors})
6.2 使用GenericAPIView+序列化类+Response写接口
class BookView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerialzier
def get(self, request):
qs = self.get_queryset()
ser = self.get_serializer(qs, many=True)
return Response({'code': 100, 'msg': '成功', 'results': ser.data})
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerialzier
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(book)
return Response({'code': 100, 'msg': '成功', 'results': ser.data})
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '更新成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类的更多相关文章
- DRF框架(五)——context传参,二次封装Response类,两个视图基类(APIView/GenericAPIView),视图扩展类(mixins),子类视图(工具视图),视图集(viewsets),工具视图集
复习 1.整体修改与局部修改 # 序列化get (给前端传递参数) #查询 ser_obj = ModelSerializer(model_obj) #只传递一个参数,默认是instance的参数,查 ...
- Django框架之drf:5、反序列化器校验部分源码分析、断言、drf之请求与响应、视图组件介绍及两个视图基类、代码部分实战
Django框架之drf 目录 Django框架之drf 一.反序列化类校验部分源码解析 二.断言 三.drf之请求 1.Request能够解析的前端传入编码格式 2.Request类中的属性和方法 ...
- drf-day5——反序列化类校验部分源码分析、断言、drf请求、drf响应、视图组件及两个视图基类、基于GenericAPIView+5个视图扩展类
目录 一.反序列化类校验部分源码解析(了解) 二.断言 三.drf之请求 3.1 Request能够解析的前端传入的编码格式 3.2 Request类有哪些属性和方法(学过) 常用参数 Respons ...
- DRF中两大视图基类APIView/GenericAPIView的介绍
(1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父类. APIView与V ...
- 【Django drf】 序列化类常用字段类和字段参数 定制序列化字段的两种方式 关系表外键字段的反序列化保存 序列化类继承ModelSerializer 反序列化数据校验源码分析
目录 序列化类常用字段类和字段参数 常用字段类 常用字段参数 选项参数 通用参数 序列化类高级用法之source source填写类中字段 source填写模型类中方法 source支持跨表查询 定制 ...
- DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用
CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()), --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...
- 我瞅瞅源码系列之---drf
我瞅瞅源码系列之---drf restful规范 从cbv到drf的视图 / 快速了解drf 视图 版本 认证 权限 节流 jwt 持续更新中...
- django-jwt token校验源码简析
一. jwt token校验源码简析 1.1 前言 之前使用jwt签发了token,里面的头部包含了加密的方式.是否有签名等,而载荷中包含用户名.用户主键.过期时间等信息,最后的签名还使用了摘要算法进 ...
- DICOM医学图形处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求(续)
转载:http://blog.csdn.net/zssureqh/article/details/39237649 背景: 上一篇博文中,在对storescp工具源文件storescp.cc和DcmS ...
- DICOM医学图像处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求
转载:http://blog.csdn.net/zssureqh/article/details/39213817 背景: 上一篇专栏博文中针对PACS终端(或设备终端,如CT设备)与RIS系统之间w ...
随机推荐
- 网络安全(中职组)-B模块:Web安全渗透测试
Web安全渗透测试任务环境说明: 服务器场景:PYsystem003(关闭链接)服务器操作系统:未知用户名:未知 密码:未知 1. 通过浏览器访问http://靶机服务器IP/1,对该页面进行渗 ...
- Android 音视频 - EGL 源码解析以及 C++ 实现
OpenGL 是一个跨平台的 API,而不同的操作系统(Windows,Android,IOS)各有自己的屏幕渲染实现.所以 OpenGL 定义了一个中间接口层 EGL(Embedded Graphi ...
- Java面试——RPC
一.RPC 服务的原理 [1]Socket 套接字:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个链接的一端称为 Socket.可以实现不同计算机之间的通信,是网络编程接口的具体实现.So ...
- Moebius兼容AlwaysOn
背景 数据库是信息化的基石,支撑着整个业务系统,发挥着非常重要的作用,被喻为"IT的心脏".因此,让数据库安全.稳定.高效地运行已经成为IT管理者必须要面对的问题.数据库在底层架构 ...
- new做了哪些事情,手写一个new
1)创建一个空对象,将构造函数中的this指向这个空对象 2)将空对象的__proto__指向构造函数的prototype原型 3)执行构造函数里面的代码,为这个空对象添加属性和方法 4)返回一个新的 ...
- MySQL与Java常用数据类型的对应关系
一.字符串数据类型: MySQL类型名 大小 用途 对应Java类名 char 0-255 bytes 定长字符串 (姓名.性别.学号) String varchar 0-65535 bytes 变长 ...
- PTA题目总结
(1)前言:第一次题目集主要考察JAVA的一些语法知识,比如,控制台的输入,输出时保留两位小数,数组的使用,第十题有点难度,当时没写出来,现在想想 也还好,就是读懂题目有点费劲,第一次题目的题量比较大 ...
- ByteHouse MaterializedMySQL 增强优化
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 前言 社区版 ClickHouse 推出了MaterializedMySQL数据库引擎,用于将 MySQL 中的表 ...
- Unity C# IEnumrator 与 async 有的区别
前言 IEnumerator 和 async 是在 Unity 和 C# 中处理异步编程的两种不同方法.它们各自有不同的使用场景和优缺点. IEnumerator IEnumerator 是 C# 中 ...
- kubernetes(k8s)命名空间一直Terminating
root@hello:~# kubectl get ns NAME STATUS AGE auth Terminating 34m default Active 23h kube-node-lease ...