04 drf源码剖析之版本
04 drf源码剖析之版本
1. 版本简述
API版本控制使您可以更改不同客户端之间的行为。REST框架提供了许多不同的版本控制方案。
版本控制由传入的客户端请求确定,并且可以基于请求URL或基于请求标头。
启用API版本控制后,该
request.version属性将包含一个字符串,该字符串与传入客户端请求中请求的版本相对应。默认情况下,版本控制未启用,并且
request.version将始终返回None。
2. 版本使用
settings配置文件
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
'ALLOWED_VERSIONS':['v1','v2'], }
路由
# 路由分发
urlpatterns = [
url(r'^api/(?P<version>\w+)/', include('api.urls')),
] # 子路由
urlpatterns = [
url(r'^order/$', views.OrderView.as_view()),
]
通过request.version可以取值
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request class OrderView(APIView):
def get(self,request,*args,**kwargs):
print(request.version)
print(request.versioning_scheme)
return Response('...') def post(self,request,*args,**kwargs):
return Response('post')
3.源码剖析
请求到来执行dispatch方法
class APIView(View):
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS def dispatch(self, request, *args, **kwargs): # 第一步
self.args = args
self.kwargs = kwargs """
request = 生成了一个新的request对象,此对象的内部封装了一些值。
request = Request(request)
- 内部封装了 _request = 老的request
"""
request = self.initialize_request(request, *args, **kwargs)
self.request = request self.headers = self.default_response_headers # deprecate? try:
# 第二步
self.initial(request, *args, **kwargs) 执行视图函数...
执行initial方法
def initial(self, request, *args, **kwargs): # 2.1 处理drf的版本
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
...
determine_version
- versioning_class是在配置文件设置的URLPathVersioning
def determine_version(self, request, *args, **kwargs):
if self.versioning_class is None:
return (None, None)
scheme = self.versioning_class() # obj = XXXXXXXXXXXX()
return (scheme.determine_version(request, *args, **kwargs), scheme)
接着去执行URLPathVersioning对象的determine_version方法
class URLPathVersioning(BaseVersioning):
"""
urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), ]
"""
invalid_version_message = _('Invalid version in URL path.') def determine_version(self, request, *args, **kwargs):
version = kwargs.get(self.version_param, self.default_version)
if version is None:
version = self.default_version if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
4. 总结
- 请求过来执行dispatch方法中的initial方法中的版本处理的determine_version方法
- 找到setings配置中版本类URLPathVersioning,对其实例化,
- 执行实例化对象的determine_version方法,
- 该方法会获取路由中输入的版本信息,
- 在is_allowed_version方法中会判断url中的版本是否在settings配置设定的ALLOWED_VERSIONS列表中
- 如果在就将版本赋值给request.version,将版本类赋值给request.versioning_scheme
04 drf源码剖析之版本的更多相关文章
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 07 drf源码剖析之节流
07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...
- 06 drf源码剖析之权限
06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...
- 05 drf源码剖析之认证
05 drf源码剖析之认证 目录 05 drf源码剖析之认证 1. 认证简述 2. 认证的使用 3. 源码剖析 4. 总结 1. 认证简述 当我们通过Web浏览器与API进行交互时,我们可以登录,然后 ...
- 02 drf源码剖析之快速了解drf
02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...
- 04 flask源码剖析之LocalStack和Local对象实现栈的管理
04 LocalStack和Local对象实现栈的管理 目录 04 LocalStack和Local对象实现栈的管理 1.源码入口 1. flask源码关于local的实现 2. flask源码关于l ...
- 01 drf源码剖析之restful规范
01 restful规范 目录 01 restful规范 1. 什么是restful规范 2.restful规范详细 1. 什么是restful规范 restful是一套规则,是程序间进行数据传输的一 ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- flask源码剖析系列(系列目录)
flask源码剖析系列(系列目录) 01 flask源码剖析之werkzurg 了解wsgi 02 flask源码剖析之flask快速使用 03 flask源码剖析之threading.local和高 ...
随机推荐
- 实现简易版react中createElement和render方法
function createElement(type, config, children) { // 1. 创建一个对象 // 2.根据参数config修改这个对象 // 3.把children参数 ...
- Flask Jinja2 知识点
Jinja2模板引擎使用以下分隔符从HTML转义. {% ... %}用于语句 {{ ... }}用于表达式可以打印到模板输出 {# ... #}用于未包含在模板输出中的注释 # ... ##用于行语 ...
- JVM面试题总结
1.介绍下 Java 内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域. JDK 1.8之前主要分为:堆.方法区.虚拟机栈.本地方法栈 ...
- cb34a_c++_STL_算法_查找算法_(7)_lower_bound
cb34a_c++_STL_算法_查找算法_(7)_lower_bound//针对已序区间的查找算法,如set,multiset关联容器-自动排序lower_bound()--第一个可能的位置uppe ...
- git常用代码合集
git常用代码合集 1. Git init:初始化一个仓库 2. Git add 文件名称:添加文件到Git暂存区 3. Git commit -m “message”:将Git暂存区的代码提交到Gi ...
- JavaWeb网上图书商城完整项目--day02-18.修改密码页面处理
1.用户登陆成功之后会显示 当点击修改密码的时候,会进入下面的页面 对应的是pwd.jsp这个文件 我们把对jsp页面前段的校验都封装在pwd.js中,在jsp中引入该js文件 <%@ page ...
- Java面试必备Springioc上
配置文件中 Proprety name值必须和 类中的成员变量private IUsedao userDao一一对应 工程项目的代码为:
- 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云
一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...
- 基数排序(Java)
基数排序(Java) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 基数排序(桶排序)介绍 基数排序(radix sort)属 ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...