04 drf源码剖析之版本

1. 版本简述

  • API版本控制使您可以更改不同客户端之间的行为。REST框架提供了许多不同的版本控制方案。

  • 版本控制由传入的客户端请求确定,并且可以基于请求URL或基于请求标头。

  • 启用API版本控制后,该request.version属性将包含一个字符串,该字符串与传入客户端请求中请求的版本相对应。

  • 默认情况下,版本控制未启用,并且request.version将始终返回None

2. 版本使用

  1. settings配置文件

    REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
    'ALLOWED_VERSIONS':['v1','v2'], }
  2. 路由

    # 路由分发
    urlpatterns = [
    url(r'^api/(?P<version>\w+)/', include('api.urls')),
    ] # 子路由
    urlpatterns = [
    url(r'^order/$', views.OrderView.as_view()),
    ]
  3. 通过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. 总结

  1. 请求过来执行dispatch方法中的initial方法中的版本处理的determine_version方法
  2. 找到setings配置中版本类URLPathVersioning,对其实例化,
  3. 执行实例化对象的determine_version方法,
  4. 该方法会获取路由中输入的版本信息,
  5. 在is_allowed_version方法中会判断url中的版本是否在settings配置设定的ALLOWED_VERSIONS列表中
  6. 如果在就将版本赋值给request.version,将版本类赋值给request.versioning_scheme

04 drf源码剖析之版本的更多相关文章

  1. drf源码剖析系列(系列目录)

    drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...

  2. 07 drf源码剖析之节流

    07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...

  3. 06 drf源码剖析之权限

    06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...

  4. 05 drf源码剖析之认证

    05 drf源码剖析之认证 目录 05 drf源码剖析之认证 1. 认证简述 2. 认证的使用 3. 源码剖析 4. 总结 1. 认证简述 当我们通过Web浏览器与API进行交互时,我们可以登录,然后 ...

  5. 02 drf源码剖析之快速了解drf

    02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...

  6. 04 flask源码剖析之LocalStack和Local对象实现栈的管理

    04 LocalStack和Local对象实现栈的管理 目录 04 LocalStack和Local对象实现栈的管理 1.源码入口 1. flask源码关于local的实现 2. flask源码关于l ...

  7. 01 drf源码剖析之restful规范

    01 restful规范 目录 01 restful规范 1. 什么是restful规范 2.restful规范详细 1. 什么是restful规范 restful是一套规则,是程序间进行数据传输的一 ...

  8. DRF源码系列分析

    DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流

  9. flask源码剖析系列(系列目录)

    flask源码剖析系列(系列目录) 01 flask源码剖析之werkzurg 了解wsgi 02 flask源码剖析之flask快速使用 03 flask源码剖析之threading.local和高 ...

随机推荐

  1. 实现简易版react中createElement和render方法

    function createElement(type, config, children) { // 1. 创建一个对象 // 2.根据参数config修改这个对象 // 3.把children参数 ...

  2. Flask Jinja2 知识点

    Jinja2模板引擎使用以下分隔符从HTML转义. {% ... %}用于语句 {{ ... }}用于表达式可以打印到模板输出 {# ... #}用于未包含在模板输出中的注释 # ... ##用于行语 ...

  3. JVM面试题总结

    1.介绍下 Java 内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域. JDK 1.8之前主要分为:堆.方法区.虚拟机栈.本地方法栈 ...

  4. cb34a_c++_STL_算法_查找算法_(7)_lower_bound

    cb34a_c++_STL_算法_查找算法_(7)_lower_bound//针对已序区间的查找算法,如set,multiset关联容器-自动排序lower_bound()--第一个可能的位置uppe ...

  5. git常用代码合集

    git常用代码合集 1. Git init:初始化一个仓库 2. Git add 文件名称:添加文件到Git暂存区 3. Git commit -m “message”:将Git暂存区的代码提交到Gi ...

  6. JavaWeb网上图书商城完整项目--day02-18.修改密码页面处理

    1.用户登陆成功之后会显示 当点击修改密码的时候,会进入下面的页面 对应的是pwd.jsp这个文件 我们把对jsp页面前段的校验都封装在pwd.js中,在jsp中引入该js文件 <%@ page ...

  7. Java面试必备Springioc上

    配置文件中 Proprety name值必须和 类中的成员变量private IUsedao  userDao一一对应 工程项目的代码为:

  8. 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云

    一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...

  9. 基数排序(Java)

    基数排序(Java) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 基数排序(桶排序)介绍 基数排序(radix sort)属 ...

  10. 暑假集训Day2 互不侵犯(状压dp)

    这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...