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. epic无法登陆怎么办【百分百解决】

    epic无法登陆怎么办(感谢吾爱破解吧www.52pjb.net)站长提供的文章教程以及解决思路,谢谢大佬,更详细的解决办法可以参考下他的网站解决的方法实例! epic登陆不上去怎么办?随着GTA5免 ...

  2. Python流程控制语句详解

    1.程序结构 计算机在解决问题时,分别是顺序执行所有语句.选择执行部分语句.循环执行部分语句,分别是:顺序结构.选择结构.循环结构.如下图: 2.选择语句 2.1最简单的if语句 Python使用保留 ...

  3. centos7 hadoop 单机模式安装配置

    前言 由于现在要用spark,而学习spark会和hdfs和hive打交道,之前在公司服务器配的分布式集群,离开公司之后,自己就不能用了,后来用ambari搭的三台虚拟机的集群太卡了,所以就上网查了一 ...

  4. 【Java入门】JDK安装和环境变量配置(Win7版)

    系统环境:Windows7 x64 安装JDK和JRE版本:1.8.0_191 1.下载JDK安装包 Oracle官网下载网址:https://www.oracle.com/technetwork/j ...

  5. nslookup使用及常用命令

    nslookup是命令行里一个常用的DNS查询工具,最常用的功能是域名解析和反向解析. 下面罗列一些常用的nslookup命令 nslookup # 进入交互模式 >域名 # 进行正向解析 &g ...

  6. SQL常用取整函数

    1.Round(column_name,decimals):用于把数值字段舍入为指定的小数位数 2.Floor(column_name): 向下取整,主要用于获得小于等于数值表达式的最大整数. 3.C ...

  7. Java 源码刨析 - 线程的状态有哪些?它是如何工作的?

    线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在. 一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组系统资源,因此线程之间的切换更加节省资源.更加轻量化,也因 ...

  8. 吃货联盟订餐系统 源代码 Java初级小项目

    咳咳,今天博主给大家写一个小的项目:吃货联盟订餐系统.博主不是大神(互联网架构师的路上ing),也是小白一个,不过是刚入门的小白^_^.项目功能也很简单:只是模拟日常的订餐流程呦,所以有错误以及功能不 ...

  9. Java深拷贝和浅拷贝的区别

    浅拷贝 被复制的对象的所有的变量都与原对象有相同的值,而所有的引用对象仍然指向原来的对象.换言之,浅拷贝 不复制引用对象. 1 class Experience { 2 private String ...

  10. IDEA创建SpringBoot的多模块项目教程

    最近在写一个多模块的SpringBoot项目,基于过程总了一些总结,故把SpringBoot多个模块的项目创建记录下来. 首先,先建立一个父工程: (1)在IDEA工具栏选择File->New- ...