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. Redis学习笔记(二十一) 事务

    文章开始啰嗦两句,写到这里共21篇关于redis的琐碎知识,没有过多的写编程过程中redis的应用,着重写的是redis命令.客户端.服务器以及生产环境搭建用到的主从.哨兵.集群实现原理,如果你真的能 ...

  2. cheerio html方法中文被编码问题

    var $ = cheerio.load("<h1><p>你好</p><em>Hello,World!</em></h1&g ...

  3. TensorFlow从0到1之TensorFlow多层感知机函数逼近过程(23)

    Hornik 等人的工作(http://www.cs.cmu.edu/~bhiksha/courses/deeplearning/Fall.2016/notes/Sonia_Hornik.pdf)证明 ...

  4. redis5.0.7集群搭建

    这里实验的是129.130.240三台服务器6个节点的部署(redis集群最低要6个节点,不然无法创建). 1.压缩包安装 #wget http://download.redis.io/release ...

  5. 【Python爬虫】HTTP基础和urllib库、requests库的使用

    引言: 一个网络爬虫的编写主要可以分为三个部分: 1.获取网页 2.提取信息 3.分析信息 本文主要介绍第一部分,如何用Python内置的库urllib和第三方库requests库来完成网页的获取.阅 ...

  6. Zookeeper客户端Apache Curator

    本文不对Zookeeper进行介绍,主要介绍Curator怎么操作Zookeeper. Apache Curator是Apache ZooKeeper的Java / JVM客户端库,Apache Zo ...

  7. 微信小程序-页面跳转与参数传递

    QQ讨论群:785071190 微信小程序页面跳转方式有很多种,可以像HTML中a标签一样添加标签进行跳转,也可以通过js中方法进行跳转. navigator标签跳转 <view class=& ...

  8. 入门大数据---Hive的搭建

    本博客主要介绍Hive和MySql的搭建:  学习视频一天就讲完了,我看完了自己搭建MySql遇到了一堆坑,然后花了快两天才解决完,终于把MySql搭建好了.然后又去搭建Hive,又遇到了很多坑,就这 ...

  9. 【asp.net core 系列】14 .net core 中的IOC

    0.前言 通过前面几篇,我们了解到了如何实现项目的基本架构:数据源.路由设置.加密以及身份验证.那么在实现的时候,我们还会遇到这样的一个问题:当我们业务类和数据源越来越多的时候,我们无法通过普通的构造 ...

  10. Markdown-it-latex2img

    Markdown-it-latex2img LaTex plugin for markdown-it markdown parser,Server side MathJax Renderer. Bac ...