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. c printf(“%d”,变量)函数

  2. 授权函数-web_set_certificate_ex

    设置证书和密钥文件属性. int web_set_certificate_ex(const char * option_list,LAST); 该函数与Loadrunner 录制设置属性中的Recor ...

  3. 如何获取Apollo上项目下的所有namespace?

    背景 项目配置迁移到Apollo之后,通过统一的配置管理及配置监听使得项目配置修改的成本大大降低. 但是,在使用Apollo的过程中,强哥也遇到一个问题:如果我们要获取Apollo下的namespac ...

  4. Numpy中的广播机制,数组的广播机制(Broadcasting)

    这篇文章把numpy中的广播机制讲的十分透彻: https://jakevdp.github.io/PythonDataScienceHandbook/02.05-computation-on-arr ...

  5. LNMP 环境更换Nginx 服务器为Tengine

    本人之前所使用 LNMP 环境一直是原生的Nginx服务器,最近几天看了好多大网站使用 淘宝团队基于Nginx开发的 Tengine 决定给自己的虚拟机也装个玩玩. 关于Tengine的介绍就不多说了 ...

  6. ZooKeeper使用入门

    ZooKeeper简介 ZooKeeper是一个分布式的,开源的分布式应用程序协调服务,是Hadoop的子项目之一.它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护.域名服务.分布式 ...

  7. 剑指 Offer 09. 用两个栈实现队列

    剑指 Offer 09. 用两个栈实现队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的 ...

  8. Nginx安装配置介绍(二)

    一:Nginx安装(Windows) 官网地址:https://nginx.org/en/download.html 解压完成后,文件目录如下: 启动Nginx: 直接双击目录下的nginx.exe, ...

  9. 提交代码到gitbub.com

    提交代码到gitbub.com touch README.md //新建说明文件 git init //在当前项目目录中生成本地git管理,并建立一个隐藏.git目录 git add . //添加当前 ...

  10. 傻瓜式教学--win10 + frp + rdpwrap + 阿里云服务器 --实现win10 多用户同时远程登录内网机

    概述: 使用win10 专业版 + frp + RDPwrap + 阿里云服务器 的组合实现win10 多用户同时远程登录内网机.使用frp 做内网穿透,将内网机的指定端口暴露在外网,通过ip+por ...