小谈DRF之版本控制相关
4. 版本控制 *
4.1 基于Django的版本控制的简单实现
直接看代码,如下:
# urls.py
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls')),
]
# app01.urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^users/$', views.UsersView.as_view()),
]
# views.py
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.request import Request
# Create your views here.
class UsersView(APIView):
def get(self, request, *args, **kwargs):
print(request._request.GET.get('version'))
print(request.query_params.get('version'))
# request._request.GET和request.query_params是等价的,可以查看Request的源码
return HttpResponse('用户列表')
在浏览器地址栏中输入:http://127.0.0.1:8000/app01/users/?version=v1
后,看显示效果:
在浏览器中的显示如下:
在控制台的显示效果如下:
其中:request._request.GET
和request.query_params
是等价的,可以查看Request的源码,如下:
4.2 基于rest framework的版本控制的简单实现
4.2.1 URL中通过GET传参(自定义)
url:http://127.0.0.1:8000/app01/users/?version=v1
其他代码一样,直接看views.py中的代码:
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.versioning import BaseVersioning
class ParamVersion(object):
def determine_version(self, request, *args, **kwargs):
return request.query_params.get('version')
class UsersView(APIView):
versioning_class = ParamVersion
def get(self, request, *args, **kwargs):
# print(request._request.GET.get('version'))
# print(request.query_params.get('version'))
print(request.version)
return HttpResponse('用户列表')
效果和上面是一样的。
4.2.2 URL中通过GET传参(使用内置的)
from rest_framework.versioning import BaseVersioning, QueryParameterVersioning
class UsersView(APIView):
versioning_class = QueryParameterVersioning
def get(self, request, *args, **kwargs):
print(request.version)
return HttpResponse('用户列表')
效果和上面也是一样的。
查看QueryParameterVersioning的源码,如下:
通过查看其源码,我们可以知道在QueryParameterVersioning的 内部帮我们实现了上述功能,而且有三个配置项:
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v2', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # 在浏览器中?version中的version,可以修改
}
4.2.3 在URL的路径中传参(推荐使用)
url:http://127.0.0.1:8000/app01/v1/users/
# app01.urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view()),
]
# views.py
from rest_framework.versioning import BaseVersioning, QueryParameterVersioning, URLPathVersioning
class UsersView(APIView):
versioning_class = URLPathVersioning
def get(self, request, *args, **kwargs):
print(request.version)
return HttpResponse('用户列表')
查看URLPathVersioning的源码,我们就知道如何写url的正则了:
4.4 全局配置
版本控制这种操作基本上都是全局配置一次就可以了,所以下面看全局配置:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v2', # 默认版本
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本
'VERSION_PARAM': 'version' # 在浏览器中?version中的version,可以修改
}
# views.py
from restframework.views import APIView
class UsersView(APIView):
def get(self, request, *args, **kwargs):
print(request.version)
return HttpResponse('用户列表')
# urls.py
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls')),
]
# app01.urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view()),
]
这样配置好后,我们在浏览器输入http://127.0.0.1:8000/app01/v1/users/
后,在控制台就会显示正常的版本;
4.5 全局配置源码分析
点开APIView的源码后就能看出来:
4.6 源码流程分析
点开dispatch()方法,查看其源码:
继续点开initial()方法,查看其源码:
通过查看initial()方法的源码,我们发现:在做认证、权限和节流之前做的版本控制操作;
现在继续看版本控制的源码,点开self.determine_version()方法,查看其源码:
4.7 反向生成URL
# app01.urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view(), name='uuu'),
]
from rest_framework.views import APIView
from django.urls import reverse
class UsersView(APIView):
def get(self, request, *args, **kwargs):
# 获取到的版本号
print(request.version)
# 版本控制类对象
print(request.versioning_scheme)
# 反向生成URL(基于restframework)
u1 = request.versioning_scheme.reverse(viewname='uuu', request=request)
print(u1)
# 反向生成URL(基于Django内置的)
u2 = reverse(viewname='uuu', kwargs={'version': 'v1'})
print(u2)
return HttpResponse('用户列表')
可以看到控制台显示如下:
此时的浏览器:
我们点开from rest_framework.versioning import BaseVersioning, QueryParameterVersioning, URLPathVersioning
中的任何一个类,都会发现有一个reverse()方法,查看其源码:
4.8 版本控制内置类
查看源码:
我们不仅可以通过URL中GET传参、URL路径传参获取版本,还可以通过请求头、namespace、子域名等获取版本号,都不是很常用,需要时可以自己看,看各个类中的注释就能大致了解。