API版本控制可以用来在不同的客户端使用不同的行为。REST框架提供了大量不同的版本设计。
版本控制是由传入的客户端请求决定的,并且可基于请求URL,或者基于请求头。
rest_framework
当使用版本控制时,request.version属性(字符串)与客户端请求的版本一致。
默认情况下,没有使用版本控制,request.version将会返回None
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS # APIView def initial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """ self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. 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) scheme = self.versioning_class() return (scheme.determine_version(request, *args, **kwargs), scheme)
除非明确设置,否则DEFAULT_VERSIONING_CLASS值为None.此例中request.version将会始终返回None
您还可以在一个单独的视图上设置版本控制方案。通常,不需要这样做,因为在全局范围内使用一个版本控制方案更有意义。如果确实需要这样做,请使用versioning_class属性。
from rest_framework.versioning import QueryParameterVersioning class VersionTestAPI(APIView): versioning_class = QueryParameterVersioning
rest_framework .versioning中的5种版本控制方式
class AcceptHeaderVersioning(BaseVersioning): """ GET /something/ HTTP/1.1 Host: example.com Accept: application/json; version=1.0 """ pass class URLPathVersioning(BaseVersioning): """ To the client this is the same style as `NamespaceVersioning`. The difference is in the backend - this implementation uses Django's URL keyword arguments to determine the version. An example URL conf for two views that accept two different versions. urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail') ] GET /1.0/something/ HTTP/1.1 Host: example.com Accept: application/json """ pass class NamespaceVersioning(BaseVersioning): """ To the client this is the same style as `URLPathVersioning`. The difference is in the backend - this implementation uses Django's URL namespaces to determine the version. An example URL conf that is namespaced into two separate versions # users/urls.py urlpatterns = [ url(r'^/users/$', users_list, name='users-list'), url(r'^/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail') ] # urls.py urlpatterns = [ url(r'^v1/', include('users.urls', namespace='v1')), url(r'^v2/', include('users.urls', namespace='v2')) ] GET /1.0/something/ HTTP/1.1 Host: example.com Accept: application/json """ pass class HostNameVersioning(BaseVersioning): """ GET /something/ HTTP/1.1 Host: v1.example.com Accept: application/json """ pass class QueryParameterVersioning(BaseVersioning): """ GET /something/?version=0.1 HTTP/1.1 Host: example.com Accept: application/json """ pass
以URLPathVersioning为例
- setting添加配置
INSTALLED_APPS = [ ... 'VersionDemo' ... ] REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本 'VERSION_PARAM':'version', # 参数 # 1 'DEFAULT_VERSION':'v1', # 默认版本 }
2.url路由配置
urls.py urlpatterns = [ re_path('api/(?P<version>[v1|v2]+)/', include('api.urls')), name='users-list'] # 2 api/urls.py urlpatterns = [ path('test/', views.VersionTestView.as_view()),]
- 传递版本信息
http://127.0.0.1:8000/api/v1/test/
- 获取版本
request.version # 获取版本
基于不同版本进行不同的行为
class VersionTestView(APIView): def get(self,request,version): # 3 1,2,3处参数要保持一至,这里均为version if request.version == 'v2': return Response({'data':'v2'}) return Response({'data':'v1'})
改变URL,如何反向解析
from rest_framework.reverse import reverse reverse('users-list', request=request)
reverse函数将应用于转换任何请求版本的URL。
- NamespacedVersioning:类似命名空间
'v1:users-list'
来源:https://www.cnblogs.com/notfind/p/12043710.html