基本代码结构

settings.py:

REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # URL中获取值的key
}

urls.py:

from django.conf.urls import url, include
from web.views import TestView urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'),
]

views.py:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning class TestView(APIView):
versioning_class = URLPathVersioning def get(self, request, *args, **kwargs):
# 获取版本
print(request.version)
# 获取版本管理的类
print(request.versioning_scheme) # 反向生成URL
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url) return Response('GET请求,响应内容') def post(self, request, *args, **kwargs):
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')

源码分析

  • 为什么会用“versioning_class”属性变量,它有什么用?

  

  还是要从APIView类中的dispatch开始说起,跟之前讲的认证等功能接口一样,首先要完成对django原生request的封装,然后同样是在initial方法中实现版本控制。在initial方法中可以看到,是通过调用determine_version方法实现版本控制。

  

  

  在determine_version方法中就可以看到versioning_class属性变量,再跳转到version_class定义的地方。可以看到,它的初始值是通过配置文件设置的,而这种方式,主要是来实现全局配置的(下文会说明全局配置)。通过全局配置和“scheme = self.versioning_class()”代码可以看出,这段代码是在做对象的实例化,所以version_class属性变量存储的是一个对象,具体是哪个对象,全局配置方法中告诉了我们。使用的就是基本代码结构中的“URLPathVersioning”对象。而这个类就是实现版本控制核心代码的类。当我们不使用全局配置时,那么我们就必须在自定义的视图类中给version_class属性变量赋值,即:version_class = URLPathVersioning。

  • 在urls.py文件中,版本的正则为什么要写成“(?P<version>[v1|v2]+)”的形式,为什么正则中的变量是“version”?

  

  跳转到URLPathVersioning类定义的地方可以看到,这种样式的正则“(?P<version>[v1|v2]+)”url的编写方式是在源码中已经规定好的,所以我们要使用源码中提供的接口。

  • 在settings配置文件中,为什么会使用“DEFUALT_VERSION”,“ALLOWED_VERSION”,“VERSION_PARM”者三个key值来做版本配置?

  由URLPathVersioning类的定义可以看出,它的父类是BaseVersioning类,先看一下这个类的具体定义。最开始定义的三个属性变量“default_version”,“allowed_versions”,“version_param”的值,也都是通过settings配置文件赋值的,而这三个值不就是问题中提到的三个key值吗?

  再看determine_version方法,它会抛出异常,所以它的子类(URLPathVersioning类)必须重写这个方法。而下面的is_allowed_version方法,就是用来判断前端请求的版本号是否是配置文件中所配置的版本之一,这就用到了allowed_versions属性变量。如果没有配置allowed_versions变量(也就是说没有设置版本控制的功能,那自然是允许通过的,返回True),如果做了版本控制,那么就要判断当前获取的版本号(version变量)是否在配置的版本中,这里就会用到default_version变量和allowed_versions变量。

  reverse方法是用于URL反射用的,这里就不多谈了。

  再回到URLPathVersioning类中,可以看到determine_version方法。在这个方法中可以看到,通过kwargs.get()来获取前端请求时的版本号,这就要用到version_param和default_version变量。值得注意的是在对version_param变量配置时,的字符串必须跟在urls.py中的正则表达式中的变量保存一致(这里用的是“version”字符串)。当version变量为None时,就使用默认的版本。之后再调用is_allowed_version方法,完成对当前版本的是否合法的判断。最后返回合法的版本号。

  

  再回到APIView类中的initial方法中,可以看到它也调用了自己的determine_version方法。在determine_version方法中,可以看到上文提到过的versioning_class属性变量,它保存了URLPathVersion类对象。再看determine_version方法的返回值,返回的是一个元组。元组第一个元素正是上文提到过的URLPathVersion类中的determine_version方法,而这个方法返回的也正是合法的版本号。元组第二个元素是就是这个版本类对象。

  再来到initial方法中,determine_version方法返回的元组的值,分别赋值到了request.version和request_versioning_scheme变量中。因此,在代码基本结构中,通过request.version变量来获取合法的版本号。

全局配置

REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version'
}

  当使用全局配置时,就不需要在自定义的视图类中使用“versioning_class = URLPathVersioning”这段代码了。

Django Rest Framework之版本控制的更多相关文章

  1. Django REST framework - 版本控制

    目录 Django REST framework 版本控制 为什么需要版本控制 DRF提供了5种版本控制方案 版本控制系统的使用 全局配置 局部配置 获取版本信息 Django REST framew ...

  2. Django REST framework反向生成url

    Django REST framework是一个基于Django的框架,REST framework又是怎么反向生成url的呢?? 在前面的例子中,知道在REST framework中有6种版本控制的 ...

  3. django rest framework restful 规范

    内容回顾: . django请求生命周期 -> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM.模板渲染) -> ...

  4. Django Rest Framework源码剖析(四)-----API版本

    一.简介 在我们给外部提供的API中,可会存在多个版本,不同的版本可能对应的功能不同,所以这时候版本使用就显得尤为重要,django rest framework也为我们提供了多种版本使用方法. 二. ...

  5. Django Rest FrameWork 全部API

    Django Rest FrameWork .Requests 请求 客服端发送给服务器的请求 .Responses 响应 rest框架支持响应不同格式的内容 .Views 视图 base基础类视图 ...

  6. Django REST Framework 学习笔记

    前言: 基于一些不错的RESTful开发组件,可以快速的开发出不错的RESTful API,但如果不了解开发规范的.健壮的RESTful API的基本面,即便优秀的RESTful开发组件摆在面前,也无 ...

  7. DRF Django REST framework APIView(一)

    什么是REST? REST是一个标准,一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用. 使url更容易理解,让增删改清晰易懂,在前后端分离开发中按照这一规范能加快开发效率,减 ...

  8. django restful framework教程大全

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  9. Django Rest Framework API指南

    Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...

随机推荐

  1. azkaban disable 停用部分工作流

    在使用azkaban作为调度工具的时候,难免遇到只需要跑工作流某部分的情况,这时需要用到停用部分工作的操作, 如图:

  2. .NET Core微服务之路:基于gRPC服务发现与服务治理的方案

    重温最少化集群搭建,我相信很多朋友都已经搭建出来,基于Watch机制也实现了出来,相信也有很多朋友有了自己的实现思路,但是,很多朋友有个疑问,我API和服务分离好了,怎么通过服务中心进行发现呢,这个过 ...

  3. Javascript百学不厌 - this

    最近看了一本书,让自己的野路子走走正规路线 方法调用模式: 方法:当一个函数被保存为对象的一个属性时,我们称它为一个方法. var obj = { fun1: function() {this} // ...

  4. 分布式任务调度系统xxl-job搭建

    为解决分布式环境下定时任务的可靠性,稳定性,只执行一次的特性,我找到了个大众点评开源的分布式调度任务解决完整系统,下面我将一步步深入解读该系统,从基本的使用到源码的探究 下载 https://gith ...

  5. Shell-14--awk

    awk ' 条件1{ 动作1} 条件2{动作2}...' 文件名 awk处理数据是 先读取第一行 然后再去处理 printf 不会加入换行符,需要手动加入 print 会自动加换行 begin 是在后 ...

  6. 鱼眼投影方式(Fisheye projection)的软件实现

    简单实现 鱼眼模式(Fisheye)和普通的透视投影(Perspective projection),一个很大的区别就是鱼眼的投影算法是非线性的(non-linear),实际照相机的情况是在镜头外面包 ...

  7. asp.net mvc 安全测试漏洞 " HTTP 动词篡改的认证旁路" 问题解决

    IBM Security Appscan漏洞筛查-HTTP 动词篡改的认证旁路漏洞,具体解决方案: 在Web.Config中system.webServer节点增加配置security: <se ...

  8. Maven - Tips

    1- Maven的Settings http://maven.apache.org/settings.html 2- Maven设置代理 示例: <proxies> <proxy&g ...

  9. python TypeError: 'int' object is not callable 问题解决

    TypeError: 'int' object is not callable 这个错误的原因很简单 看下面的程序: def loss(a,b): return a-b loss = 0 loss = ...

  10. [CTSC1999] 家园

    使用并查集判断无解. 令月球是n+1,地球是0 枚举时长t,将点(地球.月球以及太空站)i拆为t个点(i,j)表示第j时刻的点i. 对于太空船云云建图,容量是h[i]. 源点S和(0,0)连边,容量k ...