zoukankan      html  css  js  c++  java
  • rest_framework框架——版本控制组件

    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为例

    1. 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()),]
    
    1. 传递版本信息
    http://127.0.0.1:8000/api/v1/test/
    
    1. 获取版本
    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'
    
  • 相关阅读:
    postgresql客户端连接错误的解决方法【转】
    在游戏开发中使用管理类的目的和作用
    Unity3D对象池
    yield的作用
    Unity延迟和重复调用方法
    Unity的Asset Store商店下载文件路径
    C#委托和事件详解
    C#一个关于委托和事件通俗易懂的例子
    C#委托和事件定义和使用
    C#委托和事件
  • 原文地址:https://www.cnblogs.com/notfind/p/12043710.html
Copyright © 2011-2022 走看看