版本

2018-02-07  本文已影响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' 
}
上一篇下一篇

猜你喜欢

热点阅读