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. 基于JQuery的简单富文本编辑器

    利用jQuery实现最简单的编辑器 我试了很多种方法,目前最快捷能够实现及其简单的编辑可以使用 document.execCommand("ForeColor", "fa ...

  2. opencv视频教程分享

    opencv视频教程分享-在线与网盘 https://pan.baidu.com/s/1oAcctlS 密码:i5rd 链接:https://pan.baidu.com/s/1kVJ3iSJ  密码: ...

  3. 【Java】HashMap实现原理---数据结构

    作为一个程序猿,特别是Java后端的,应该全部人都用过HashMap,也都知道HaspMap是一个用于存储Key-Value键值对的集合.与此同时我们把每一个键值对也叫做 Entry. 而这些Entr ...

  4. elasticsearch中query和filter的区别

    参考博客来自: https://mp.weixin.qq.com/s/tiiveCW3W-oDIgxvlwsmXA?utm_medium=hao.caibaojian.com&utm_sour ...

  5. junit基本介绍视频笔记1

    程序员每天工作的基本流程: 1.从svn检出代码: 2.运行单元测试,测试无误,进入下一步: 3.开始一天的代码编写工作: 4.代码提交到服务器之前进行单元测试: 5.单元测试通过提交到svn服务器. ...

  6. set dict tuple 内置方法

    今日内容 * 元祖及内置方法* 字典及内置方法* 集合及内置方法* 字符编码 元祖tuple 与列表类似可以存多个值,但是不同的是元祖本身不能被修改 ```python一:基本使用:tuple 1 用 ...

  7. Python3-shutil模块-高级文件操作

    Python3中的shutil模块提供了对文件和容器文件的一些高级操作 shutil.copy(src, dst) 拷贝文件,src和dst为路径的字符串表示,copy()会复制文件数据和文件权限,但 ...

  8. Java 比较对象中的内容是否一致

    获取对象中的所有属性 private static Field[] getAllFields(Object object) { Class clazz = object.getClass(); Lis ...

  9. Windows10系统下安装配置Tomcat 9.0.1

    Tomcat9.0.1下载:https://tomcat.apache.org/download-90.cgi 配置jdk的环境变量(略) 在系统变量里新建变量名:CATALINA_BASE,变量值: ...

  10. Python实用笔记 (26)面向对象高级编程——定制类

    Python的class允许定义许多定制方法,可以让我们非常方便地生成特定的类.以下是集中常见的定制方法: 怎么才能打印得好看呢?只需要定义好__str__()方法,返回一个好看的字符串就可以了: _ ...