API版本控制使您可以更改不同客户端之间的行为。REST框架提供了许多不同的版本控制方案。
版本控制由传入的客户端请求确定,并且可以基于请求URL或基于请求标头。
启用API版本控制后,该request.version
属性将包含一个字符串,该字符串与传入客户端请求中请求的版本相对应。
默认情况下,版本控制未启用,并且request.version
将始终返回None
。
settings配置文件
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
'ALLOWED_VERSIONS':['v1','v2'],
}
路由
# 路由分发
urlpatterns = [
url(r'^api/(?P<version>\w+)/', include('api.urls')),
]
# 子路由
urlpatterns = [
url(r'^order/$', views.OrderView.as_view()),
]
通过request.version可以取值
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
class OrderView(APIView):
def get(self,request,*args,**kwargs):
print(request.version)
print(request.versioning_scheme)
return Response('...')
def post(self,request,*args,**kwargs):
return Response('post')
请求到来执行dispatch方法
class APIView(View):
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
def dispatch(self, request, *args, **kwargs):
# 第一步
self.args = args
self.kwargs = kwargs
"""
request = 生成了一个新的request对象,此对象的内部封装了一些值。
request = Request(request)
- 内部封装了 _request = 老的request
"""
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 第二步
self.initial(request, *args, **kwargs)
执行视图函数...
执行initial方法
def initial(self, request, *args, **kwargs):
# 2.1 处理drf的版本
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
...
determine_version
def determine_version(self, request, *args, **kwargs):
if self.versioning_class is None:
return (None, None)
scheme = self.versioning_class() # obj = XXXXXXXXXXXX()
return (scheme.determine_version(request, *args, **kwargs), scheme)
接着去执行URLPathVersioning对象的determine_version方法
class URLPathVersioning(BaseVersioning):
"""
urlpatterns = [
url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
]
"""
invalid_version_message = _('Invalid version in URL path.')
def determine_version(self, request, *args, **kwargs):
version = kwargs.get(self.version_param, self.default_version)
if version is None:
version = self.default_version
if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
原文:https://www.cnblogs.com/liubing8/p/11939525.html