1. GET傳參獲取版本
RESTful規範中規定版本可以放到URL上,如 http://127.0.0.1:8000/api/users/?version=v2
通過GET進行傳參。自定義版本實現:
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:
def determine_version(self, request, *args, **kwargs):
# version = request._request.GET.get('version')
version = request.query_params.get('version')
return version
class UsersView(APIView):
versioning_class = ParamVersion # request.version就會有值
def get(self, request, *args, **kwargs):
# request是Request的對象,如果封裝的request沒有回通過getattr方法到原生的Django的request中找
# version = request._request.GET.get('version')
# version = request.query_params.get('version')
version = request.version
# print(request.version)
return HttpResponse('%s' % version)
如果使用內置的版本類,實際上我們 不需要再自定義獲取版本的類
,直接在視圖類方法中通過 request.version
獲取就可以,因爲內置已經幫我們實現了。藉助內置類,我們可以少寫很多代碼:
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.versioning import QueryParameterVersioning
class UsersView(APIView):
versioning_class = QueryParameterVersioning
def get(self, request, *args, **kwargs):
version = request.version
return HttpResponse('%s' % version)
可以在配置文件中做默認的配置:
REST_FRAMEWORK = {
'DEFAULT_VERSION': 'v1', # 不傳參或者version寫錯了則獲取到的版本號是v1
'ALLOWED_VERSIONS': ['v1', 'v2'], # 版本號必須是v1或者v2,否則報錯如:http://xxx/api/users/?version=v3
'VERSION_PARAM': 'version',
}
2. URL路徑獲取版本
通過GET進行傳參用的相對少一些,比較多的是在URL路徑上傳參,即 ``。只需要修改URL,然後在視圖中引入 URLPathVersioning
內置版本類:
api/urls.py:
from django.urls import path, re_path
from . import views
urlpatterns = [
# path('/users/', views.UsersView.as_view()),
re_path('(?P<version>[v1,v2]+)/users/', views.UsersView.as_view()),
]
版本是一次性配置,可以把版本的類加入到配置文件中:
settings.py:
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 使用URL路徑,下面的參數可以不配置,只要URL正則匹配就可以
'DEFAULT_VERSION': 'v1', # 不傳參或者version寫錯了則獲取到的版本號是v1
'ALLOWED_VERSIONS': ['v1', 'v2'], # 版本號必須是v1或者v2,否則報錯如:http://xxx/api/users/?version=v3
'VERSION_PARAM': 'version',
}
GET傳參適用的內置類QueryParameterVersioning也可以放到配置文件中,這樣降低了類和類之間的耦合度。
views.py:
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
class UsersView(APIView):
def get(self, request, *args, **kwargs):
version = request.version
return HttpResponse('%s' % version)
3. 內置版本類源碼流程
通過reserve反向生成url:
from django.urls import path, re_path
from . import views
urlpatterns = [
# path('users/', views.UsersView.as_view()),
re_path('(?P<version>[v1,v2]+)/users/', views.UsersView.as_view(), name='user'),
]
from django.shortcuts import HttpResponse
from rest_framework.views import APIView
class UsersView(APIView):
def get(self, request, *args, **kwargs):
# 獲取版本
version = request.version
# 獲取處理版本的對象
versioning_scheme = request.versioning_scheme
# 所有的版本類對象中有reverse方法用來反向生成url的,版本自動生成。不需要加上version參數,request=request表示在request自動設置上當前的版本
url = request.versioning_scheme.reverse(viewname='user', request=request)
self.dispatch
return HttpResponse('%s' % (url,))
也可以適用Django的反向生成url,只不過要手動加上版本參數:
4. 內置版本類
Django REST framework內置了5個版本類,自定義版本類需要繼承BaseVersioning,但是一般我們不需要自定義,內置的已經夠我們使用的。QueryParameterVersioning是通過在URL中使用GET傳參;URLPathVersioning是URL路徑;HostNameVersioning是基於子域名做的;NamespaceVersioning是基於namespace,但是不常用;AcceptHeaderVersioning是基於請求頭。
放到cookie中也是可以的,只要後端能正常接收。