版本

作者: 马小跳_ | 来源:发表于2018-02-07 16:54 被阅读5次

    源码流程

    # 第一步:请求到来先执行APIView.dispatch
    APIView.dispatch(self, request, *args, **kwargs)
    
    # 第二步:APIView.dispatch指向APIView.initial
    APIView.initial(request, *args, **kwargs)
    
    # 第三步:APIView.initial中指向APIView.determine_version,
    # 在APIView.determine_version内部执行了配置的versioning_class的determine_version方法
    version, scheme = self.determine_version(request, *args, **kwargs)
    APIView.determine_version(self, request, *args, **kwargs):
        scheme = self.versioning_class()
        return (scheme.determine_version(request, *args, **kwargs), scheme)
    URLPathVersioning.determine_version(self, request, *args, **kwargs):
        return version
    
    # 第四步:将版本号和versioning_class的实例封装到request中
    request.version, request.versioning_scheme = version, scheme
    
    # 第五步:使用
    class QueryParamVersionView(APIView):
        versioning_class = QueryParameterVersioning  # 配置版本类
        def get(self, request, *args, **kw):
            print(request.version)  # 接收到的版本号
            print(request.versioning_scheme)  # 版本类的实例
            return Response('...')
    

    使用

    这里列举了三种常用的版本方式

    settings.py

    REST_FRAMEWORK = {
        'DEFAULT_VERSION': 'v1',            # 默认版本
        'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本
        'VERSION_PARAM': 'v'          # URL中获取值的key
    }
    

    urls.py

    urlpatterns = [
        url(r'^queryparam/', views.QueryParamVersionView.as_view(), name='queryparam'),
        url(r'^(?P<v>[v1|v2]+)/urlpath/', views.URLPathVersionView.as_view(), name='urlpath'),
        url(r'^hostname/', views.HostNameVersion.as_view(), name='hostname'),
    ]
    

    views.py

    from django.shortcuts import render
    from rest_framework.response import Response
    from rest_framework.views import APIView
    from rest_framework.versioning import QueryParameterVersioning, URLPathVersioning, HostNameVersioning
    
    class QueryParamVersionView(APIView):
        versioning_class = QueryParameterVersioning  # 基于url的get传参方式  http://127.0.0.1:8000/api/queryparam/?v=v2
    
        def get(self, request, *args, **kw):
            print(request.version)  # 接收到的版本号
            print(request.versioning_scheme)  # 版本类的实例
    
            # 版本类的reverse方法只能反向生成当前版本的url
            reverse_url = request.versioning_scheme.reverse('queryparam', request=request)
            print(reverse_url)
    
            # django的reverse方法可以反向生成任意版本的url
            from django.urls import reverse
            from urllib.parse import urlencode
            base_url = reverse('queryparam')
            reverse_url = "%s?%s" % (base_url, urlencode({'v': 'v1'}))
            print(reverse_url)
            return Response('...')
    
    class URLPathVersionView(APIView):
        versioning_class = URLPathVersioning  # 基于url的正则方式 http://127.0.0.1:8000/api/v1/urlpath/
    
        def get(self, request, *args, **kw):
            print(request.version)  # 接收到的版本号
            print(request.versioning_scheme)  # 版本类的实例
    
            # 版本类的reverse方法只能反向生成当前版本的url
            reverse_url = request.versioning_scheme.reverse('urlpath', request=request)
            print(reverse_url)
    
            # django的reverse方法可以反向生成任意版本的url
            from django.urls import reverse
            reverse_url = reverse('urlpath', kwargs={'v': 'v2'})
            print(reverse_url)
            return Response('...')
    
    class HostNameVersion(APIView):
        versioning_class = HostNameVersioning  # 基于主机名方法  http://v1.example.com:8000/api/hostname/
    
        def get(self, request, *args, **kw):
            print(request.version)  # 接收到的版本号
            print(request.versioning_scheme)  # 版本类的实例
    
            # 版本类的reverse方法只能反向生成当前版本的url
            reverse_url = request.versioning_scheme.reverse('hostname', request=request)
            print(reverse_url)
    
            # django的reverse方法可以反向生成任意版本的url
            from django.urls import reverse
            base_url = reverse('hostname')
            reverse_url = "http://%s.example.com:8000/api/hostname/" % 'v1'
            print(reverse_url)
            return Response('...')
    

    全局使用

    REST_FRAMEWORK = {
        'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
        'DEFAULT_VERSION': 'v1',
        'ALLOWED_VERSIONS': ['v1', 'v2'],
        'VERSION_PARAM': 'version' 
    }
    

    相关文章

      网友评论

          本文标题:版本

          本文链接:https://www.haomeiwen.com/subject/emrazxtx.html