随着程序越来越大,可能通过版本不同,做出不同的处理方式。没用rest_framwork之前,我们可能会这样做:
class UserView(APIView): def get(self,request,*args,**kwargs): version = request.query_params.get('version') print(version) if version=='v1': #如果版本是v1 ret = { 'code':111, 'msg':'版本一的内容' } elif version=='v2': # 如果是v2 ret = { 'code': 112, 'msg': '版本二的内容' } else: ret = { 'code': 0, 'msg': '不支持其他版本' } return Response(ret)
通过rest_framework实现:
先看源码:
进行认证之前,先获取版本
控制类实现方式有多种:局部使用时在CBV添加versioning_class 参数,值为版本控制类名。全局使用在settings中设置即可。
使用方法:
QueryParameterVersioning类:url参数
# 版本测试 path('test_version/', views.TestVersionsView.as_view(), name='test_list'), # 匿名测试
from rest_framework.versioning import QueryParameterVersioning from rest_framework.response import Response # from django.urls import reverse class TestVersionsView(APIView): versioning_class = QueryParameterVersioning def get(self, request): version = request.version if version == 'v1': return Response('版本一') elif version == 'v2': versioning_scheme = request.versioning_scheme # 版本类对象,用于反向生成url url = versioning_scheme.reverse(viewname='test_list', request=request) # 接收一个url别名与request # print(versioning_scheme, type(versioning_scheme)) print(url) return Response('版本二') else: return Response("ok")
request.version接收版本号,versioning_scheme接收版本控制类对象用来调用版本控制类下的反向解析url方法。django内置的方法同样可以进行反向解析,但只适用使用版本控制类URLPathVersioning
URLPathVersioning类:url路由
# 版本测试URLPathVersioning re_path("test_version_path/(?P<version>[v1|v2]+)", views.TestVersionsPathView.as_view(), name='test_list2')
from rest_framework.versioning import URLPathVersioning class TestVersionsPathView(APIView): versioning_class = URLPathVersioning def get(self, request, *args, **kwargs): version = request.version versioning_scheme = request.versioning_scheme print(request.version) if version == 'v1': url = reverse(viewname='test_list2', kwargs={"version": "v1"}) print(url) # /test_version_path/v1 return Response('版本一') elif version == 'v2': url = versioning_scheme.reverse(viewname='test_list2', request=request) print(url) # http://127.0.0.1:8000/test_version_path/v2 return Response('版本二') else: return Response('ok')
NamespaceVersioning类:include分发
# 版本测试NamespaceVersioning path('version1/', include('app01.urls', namespace='v1')), path('version2/', include('app01.urls', namespace='v2'))
from django.urls import path, re_path, include from app01 import views app_name = 'app01' urlpatterns = [ path('test_version/', views.TestNamespaceVersionsView.as_view(), name='users-list'), ]
from rest_framework.versioning import NamespaceVersioning class TestNamespaceVersionsView(APIView): versioning_class = NamespaceVersioning def get(self, request, *args, **kwargs): version = request.version versioning_scheme = request.versioning_scheme if version == 'v1': return Response('版本一') elif version == 'v2': url = versioning_scheme.reverse(viewname='users-list', request=request) print(url) return Response('版本二') else: return Response('ok')
HostNameVersioning:子域名
#分发url urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ] urlpatterns = [ url(r'^users/', views.UsersView.as_view(),name='u'), ] class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch print(request.version) # QueryParameterVersioning().detemiin_version() print(request.versioning_scheme) # QueryParameterVersioning() REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" } # C:WindowsSystem32driversetc # vim /etc/hosts 127.0.0.1 v1.luffy.com 127.0.0.1 v2.luffy.com #配置ALLOWED_HOSTS = ['*']
全局设置版本控制:在settings中设置
REST_FRAMEWORK = { ... # 使用那种版本控制来控制版本号 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', 'DEFAULT_VERSION': 'v1', # 默认的版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 有效的版本 'VERSION_PARAM': 'version', # 版本的参数名与URL conf中一致 }