1、版本
这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
感激相遇 你好 我是y大壮
作者:y大壮
链接:juejin.cn/user/756923… 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
🌊🌈关于前言:
文章部分内容及图片出自网络,如有问题请与我本人联系
🌊🌈关于内容:
主要是配置settings.py版本信息,然后在参考把版本信息是反正url,还是请求头.....哪里哪里。。
1.1 自定义版本
自定义: http://127.0.0.1:8000/api/users/?version=v2
class ParamVersion(object):
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get('version')
return version
class UsersView(APIView):
versioning_class = ParamVersion # 注意这里是当个,不是列表了
def get(self,request,*args,**kwargs):
#version = request._request.GET.get('version')
#print(version)
# version = request.query_params.get('version')
# print(version)
print(request.version)
return HttpResponse('用户列表')
1.2 使用自带的版本
# 使用:
配置文件:
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 版本信息
"DEFAULT_VERSION": 'v1', # 默认版本号,默认值为None
"ALLOWED_VERSIONS": ['v1', 'v2'], # 允许请求的版本号,默认值为None
"VERSION_PARAM": 'version', # 识别版本号参数的名称,默认值为'version'
}
路由:
urlpatterns = [ # 主路由
url(r'^api/', include('api.urls')),
]
urlpatterns = [
# http://127.0.0.1:8000/api/v1/users/
# http://127.0.0.1:8000/api/v2/users/
url(r'^(?P<version>[v1|v2]+)/users/$', views.UsersView.as_view(),name='uuu'),
]
# views.py
class UsersView(APIView):
permission_classes = []
def get(self, request, *args, **kwargs):
# 1. 获取版本 v1
print(request.version)
# 2. 获取处理版本的对象 <rest_framework.versioning.URLPathVersioning object at 0x000001C3AA7D3E10>
print(request.versioning_scheme)
# 3. 反向生成URL(rest framework) http://127.0.0.1:8000/api/v1/users/
u1 = request.versioning_scheme.reverse(viewname='uuu', request=request)
print(u1)
# 4. 反向生成URL /api/2/users/
u2 = reverse(viewname='uuu', kwargs={'version': 2})
print(u2)
return HttpResponse('用户列表')
注意
request.version
request.versioning_scheme
request.versioning_scheme.reverse(viewname='uuu', request=request)
reverse(viewname='uuu', kwargs={'version': 2})
1.3 注意
在需要获取请求的版本号时,可以通过request.version
来获取版本号。
默认版本功能未开启,request.version
返回None。
开启版本支持功能,需要在配置文件中设置DEFAULT_VERSIONING_CLASS
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 版本信息
其他可选配置:
- DEFAULT_VERSION 默认版本号,默认值为None
- ALLOWED_VERSIONS 允许请求的版本号,默认值为None
- VERSION_PARAM 识别版本号参数的名称,默认值为'version'
1.4 更多支持的版本处理方式
1) AcceptHeaderVersioning
请求头中传递的Accept携带version版本信息
GET /bookings/ HTTP/1.1
Host: example.com
Accept: application/json; version=1.0
2)URLPathVersioning(推荐使用)
URL路径中携带版本信息
urlpatterns = [
url( r'^(?P<version>(v1|v2))/bookings/$', bookings_list,name='bookings-list' ),
url( r'^(?P<version>(v1|v2))/bookings/(?P<pk>[0-9]+)/$',bookings_detail,name='bookings-detail')
]
3)NamespaceVersioning
命名空间中定义
# bookings/urls.py
urlpatterns = [
url(r'^$', bookings_list, name='bookings-list'),
url(r'^(?P<pk>[0-9]+)/$', bookings_detail, name='bookings-detail')
]
# urls.py
urlpatterns = [
url(r'^v1/bookings/', include('bookings.urls', namespace='v1')),
url(r'^v2/bookings/', include('bookings.urls', namespace='v2'))
]
4)HostNameVersioning
主机域名携带 版本信息
GET /bookings/ HTTP/1.1
Host: v1.example.com
Accept: application/json
5)QueryParameterVersioning
查询字符串携带 版本信息
GET /something/?version=0.1 HTTP/1.1
Host: example.com
Accept: application/json
示例
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning'
}
class BookInfoSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
class BookInfoSerializer2(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date')
class BookDetailView(RetrieveAPIView):
queryset = BookInfo.objects.all()
def get_serializer_class(self):
if self.request.version == '1.0':
return BookInfoSerializer
else:
return BookInfoSerializer2
# 127.0.0.1:8000/books/2/
# 127.0.0.1:8000/books/2/?version=1.0
1.5 源码流程
# 1.APIView下的dispatch方法
def dispatch(self, request, *args, **kwargs):
# 2. 进入认证self.initial(request, *args, **kwargs)
def initial(self, request, *args, **kwargs):
# 版本信息
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
# 实现认证
self.perform_authentication(request)
# 权限判断
self.check_permissions(request)
# 限流
self.check_throttles(request)
# 进入 self.determine_version(request, *args, **kwargs)
def determine_version(self, request, *args, **kwargs):