drf通篇概览
在线预览drf.pdf思维导图.
# ☆ 重要理解
(¯︶¯) 看似这个理解很重要,实则确实真的很重要!!
认证、权限、限流
举例: 请求1访问的是视图类A的 GET接口,请求2访问的是视图类A的 POST接口.
按照初学者的认知,在视图类A里配置类变量 authentication_classes、permission_classes、throttle_classes
那么,不管是请求1 还是请求2来
这些类变量背后的 多个认证类、多个权限类、多个限流类 是作用于 视图类A里的 所有接口的/GET接口、POST接口!!
这背后的代码逻辑 关键是对这个请求(即request) 进行认证权限限流,它会管你这次请求是什么类型吗? 不会!!
真实的应用场景里,很多情况都是 打个比方:请求1不需要限流,请求2需要限流.
要实现它,我们就要 对这个请求(即request)进行一点限制,
比如:该请求是POST请求才进行限流."也就是在执行 限流的源码之前,判断self.request.method!!符合我们的预期才让它往下走."
-ps- 在视图类的任一实例方法里,都可通过 self.request 拿到 drf的request!!
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# ☆ drf源码大致流程
-1- 自己写的视图类, .as_view() 得到一个闭包.
-2- 路由匹配成功后,加括号传路由参数进去,执行该闭包. 闭包里 首先进行类实例化,接着执行APIView的dispatch方法.
-3-
self.args = args
self.kwargs = kwargs
Django request的二次封装 注:__getattr__与__getattribute__; query_params
self.request = request
try: 注:★它们向上raise的异常都能在这里捕获到!
版本
认证 源码切入点request.user ; "延迟加载" ;
权限
限流
反射执行视图函数
except:
返回
-4- 解析器
-5- 序列化器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
再简单解释下:
版本
- 三个渠道传递版本信息,?params、路由、请求头 设置版本类后,若版本合法性验证通过, request.version中可取到
- 同一接口要同时支持网页端和小程序, 在视图函数中判断request.version,然后写相应的代码即可!
认证
- 要有登陆凭证才能访问 登陆凭证可能出现的地方?params、请求头等.
- 认证类返回什么? raise (user,auth) None ; 当所有认证类返回None或者不进行认证 那么就是匿名访问
- 只要不是raise , 即(user,auth) or 匿名访问<两种> 都可走到权限!
权限
- 一个权限类就是一个条件
- 权限类返回什么? raise True False; 默认所有的权限类返回True,权限才通过,可扩展为"或"关系
- 默认 raise、False 走不到限流, 全True or 不进行权限 才能走到限流.
限流
- 每一个限流类都可看作是一个kv键值对 >> 限流类里get_cache_key的返回值/唯一凭证 : [时间戳列表]
分析限流类作用于哪些接口,访问这些接口里任一接口时, 时间戳列表长度都会加1/消耗一次机会.
单位时间里时间戳列表的长度不能超过我们所设定的!否则该限流类不通过.
- 限流allow_request方法默认返回值只有True和Fasle 表明该限流类是否通过. 多个限流类不通过的话,告知最大等待时间.
可扩展,只要有一个限流类不通过就直接raise,不执行下一个限流类啦!
解析器
- 执行request.data开始触发解析动作,解析请求体中的数据 三种编码格式!
- 原理: 将请求头匹配的 解析器 筛选出来,然后解析器使用parse方法,解析body里的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ☆ 源码扩展亮点
1. 权限扩展 "或" 关系 -- 重写check_permissions方法,结合继承更好
2. 通常认证类、权限类、限流类配置到 视图类中,就是作用于该视图类中的 所有视图函数/所有接口.
同一视图类中的不同接口 是否需要认证 / 应满足不同的条件 / 是否需要限流不,限流的速率不同 等
-- 重写get_authenticators、get_permissions、get_throttles方法 <self.request.method>
>> 本质就是 真正执行 认证、权限、限流 的源码之前,将请求处理的颗粒度细化到 视图类的某个接口上!(原本颗粒度是视图类里的所有接口)
3. 限流不通过,错误信息提示的格式是固定了的.
我们可以自己写一个类来继承 APIException,来编写自己想要返回的格式!!
4. 限流allow_request方法默认返回值只有True和Fasle, 我们新增一种 raise.
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8