Django Rest Framework之版本控制
基本代码结构
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之版本控制的更多相关文章
- Django REST framework - 版本控制
目录 Django REST framework 版本控制 为什么需要版本控制 DRF提供了5种版本控制方案 版本控制系统的使用 全局配置 局部配置 获取版本信息 Django REST framew ...
- Django REST framework反向生成url
Django REST framework是一个基于Django的框架,REST framework又是怎么反向生成url的呢?? 在前面的例子中,知道在REST framework中有6种版本控制的 ...
- django rest framework restful 规范
内容回顾: . django请求生命周期 -> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM.模板渲染) -> ...
- Django Rest Framework源码剖析(四)-----API版本
一.简介 在我们给外部提供的API中,可会存在多个版本,不同的版本可能对应的功能不同,所以这时候版本使用就显得尤为重要,django rest framework也为我们提供了多种版本使用方法. 二. ...
- Django Rest FrameWork 全部API
Django Rest FrameWork .Requests 请求 客服端发送给服务器的请求 .Responses 响应 rest框架支持响应不同格式的内容 .Views 视图 base基础类视图 ...
- Django REST Framework 学习笔记
前言: 基于一些不错的RESTful开发组件,可以快速的开发出不错的RESTful API,但如果不了解开发规范的.健壮的RESTful API的基本面,即便优秀的RESTful开发组件摆在面前,也无 ...
- DRF Django REST framework APIView(一)
什么是REST? REST是一个标准,一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用. 使url更容易理解,让增删改清晰易懂,在前后端分离开发中按照这一规范能加快开发效率,减 ...
- django restful framework教程大全
一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...
- Django Rest Framework API指南
Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...
随机推荐
- yesno孤立词识别kaldi脚本
path.sh主要设定路径等 export KALDI_ROOT=`pwd`/../../.. [ -f $KALDI_ROOT/tools/env.sh ] && . $KALDI_ ...
- 使用广播-BroadcastReceiver最详细解析
女孩:BroadcastReceiver是什么呀? 男孩:Broadcast是广播的意思,在Android中应用程序之间的传输信息的机制,BroadcastReceiver是接收广播通知的组件,广播和 ...
- Android开发工程师文集-1 小时学会SQLite
前言 大家好,给大家带来Android开发工程师文集-1 小时学会SQLite的概述,希望你们喜欢 内容 什么是Sqlite: 效率高,开源,小型,程序驱动,支持事务操作,无数据类型,可嵌入的关系型数 ...
- 有没有人曾告诉你,你的SQL又报错了?[开发篇]
引语:线上运行的真实环境总是变幻莫测,明明你在本地测试的时候各种情况都是OK得不要不要的,也许你还在为自己某个地方炫酷的效果以及神奇的设计感到激动不已!但是,到线上以后,他就会偶尔跟抽风一样的跟你sa ...
- Taglist: Exuberant ctags (http://ctags.sf.net) not found in PATH. Plugin is not loaded
1 开发环境 Ubuntu16.04(64bit) 2 错误描述 安装好Vim的TagList插件后,打开Vim提示: 3 解决方法 根据参考资料[1]的提示,可知那是因为当前系统没有安装ctags导 ...
- iOS-Xcode解决【workspace integrity couldn't load project'】
出现如标题提示的项目打不开情况,多半可能是因为Xcode版本不同,或者是SVN/Git使用导致 解决办法一: 删除冲突代码,"项目文件->Pod文件夹->Pods.xcodepr ...
- 12-部署EFK插件
配置和安装 EFK 官方文件目录:cluster/addons/fluentd-elasticsearch $ ls *.yaml es-controller.yaml es-service.yaml ...
- Docker总结(脑图图片)
- Hadoop项目实战-用户行为分析之应用概述(三)
1.概述 本课程的视频教程地址:<项目工程准备> 本节给大家分享的主题如下图所示: 下面我开始为大家分享今天的第三节的内容——<项目工程准备>,接下来开始分享今天的内容. 2. ...
- Facelets应用程序的生命周期
当客户端(如浏览器)向使用Facelets创建的页面发出新的请求时,会创建一个新的组件树或 javax.faces.component.UIViewRoot将其创建并放入FacesContext. 该 ...