from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
class ParamVersion(object):
def determine_version(self,request,*args,**kwargs):
version = request._request.GET.get("version")
return version
class UserView(APIView):
versioning_class = ParamVersion
def get(self,request,*args,**kwargs):
# version = request._request.GET.get("version")
# print(version)
#
# version1 = request.query_params.get("version")
# print(version1)
print(request.version)
return HttpResponse("用户列表")
- 1.2:小知识点,我们在通过request获取信息时,先看restframework中有没有,如果没有就取原生request中的方法。实现原理
class Request:
@property
def query_params(self):
"""
More semantically correct name for request.GET.
"""
return self._request.GET
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
_request = self.__getattribute__("_request")
return getattr(_request, attr)
except AttributeError:
return self.__getattribute__(attr)
- 1.3:restframework已经有内置类帮我们实现了上面的功能
# 全局配置
REST_FRAMEWORK = {
"DEFAULT_VERSION":"v1",
"ALLOWED_VERSIONS":["v1","v2"],
"VERSION_PARAM":"version",
}
# 视图
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
class UserView(APIView):
versioning_class = QueryParameterVersioning
def get(self,request,*args,**kwargs):
print(request.version)
return HttpResponse("用户列表")
- 1.3.2:原理
class QueryParameterVersioning(BaseVersioning):
"""
GET /something/?version=0.1 HTTP/1.1
Host: example.com
Accept: application/json
"""
invalid_version_message = _('Invalid version in query parameter.')
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get(self.version_param, self.default_version)
if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
url = super().reverse(
viewname, args, kwargs, request, format, **extra
)
if request.version is not None:
return replace_query_param(url, self.version_param, request.version)
return url
# urls.py
from django.urls import path,re_path
from api import views
urlpatterns = [
re_path(r'^(?P<version>[v1|v2]+)/users/$', views.UserView.as_view()),
]
# 视图
from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
class UserView(APIView):
versioning_class = URLPathVersioning
def get(self,request,*args,**kwargs):
print(request.version)
return HttpResponse("用户列表")
- 3.源码流程
- 3.1:还是走dispatch-->>initial
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
def determine_version(self, request, *args, **kwargs):
"""
If versioning is being used, then determine any API version for the
incoming request. Returns a two-tuple of (version, versioning_scheme)
"""
if self.versioning_class is None:
return (None, None)
# 处理版本类的对象,URLPathVersioning对象
scheme = self.versioning_class()
return (scheme.determine_version(request, *args, **kwargs), scheme)
# 取版本
request.version
# 取处理版本的对象
request.versioning_scheme
urlpatterns = [
re_path(r'^(?P<version>[v1|v2]+)/users/$', views.UserView.as_view(),name='uuu'),
]
# 视图
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning
class UserView(APIView):
versioning_class = URLPathVersioning
def get(self,request,*args,**kwargs):
print(request.version)
u1 = request.versioning_scheme.reverse(viewname='uuu',request=request)
print(u1)
return HttpResponse("用户列表")