流程:

  1. 执行self.initial(request, *args, **kwargs) 方法
  2. 获取版本version, scheme = self.determine_version(request, *args, **kwargs)

settings 文件全局配置:

'DEFAULT_VERSION': 'v1', #默认版本号
    'VERSION_PARAM': 'version', #指定参数
    'ALLOWED_VERSIONS': ['v1', 'v2'], #允许访问的版本号

自定义:

class Myversion(BaseVersioning):
    def determine_version(self, request, *args, **kwargs):
        # version = request._request.GET.get("version")
        version = request.query_params.get("version")
        return (version, ) # scheme 版本对象
        
# determine_version返回后,设置到version, versioning_scheme
# version, scheme = self.determine_version(request, *args, **kwargs)
# request.version, request.versioning_scheme = version, scheme赋值

# request.query_params(封装方法) == request._request.GET

class Myview(APIView):
	versioning_class = Myversion #指定版本获取类
	
    def get(self, request, *args, **kwargs):
        print(request.version) #直接获取值
        print(request.versioning_scheme)
        return Response("ok")

内置方法:

  1. QueryParameterVersioning 查询字符串方式
def determine_version(self, request, *args, **kwargs):
        version = request.query_params.get(self.version_param, self.default_version) 
        # version_param   为settings中的 VERSION_PARAM
        # default_version 为settings中的 DEFAULT_VERSION
        # is_allowed_version 判断是否在 ALLOWED_VERSIONS列表中
        if not self.is_allowed_version(version):
            raise exceptions.NotFound(self.invalid_version_message)
        return version
  1. URLPathVersioning通过路由变量方式
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')
    ]

def determine_version(self, request, *args, **kwargs):
    version = kwargs.get(self.version_param, self.default_version) #通过传递的变量获取
    if version is None:
        version = self.default_version

    if not self.is_allowed_version(version):
        raise exceptions.NotFound(self.invalid_version_message)
    return version
  1. HostNameVersioning 通过子域名的方式
"""
    GET /something/ HTTP/1.1
    Host: v1.example.com
    Accept: application/json
    """
	hostname_regex = re.compile(r'^([a-zA-Z0-9]+)\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$')
    invalid_version_message = _('Invalid version in hostname.')

    def determine_version(self, request, *args, **kwargs):
        hostname, separator, port = request.get_host().partition(':')
        match = self.hostname_regex.match(hostname)
        if not match:
            return self.default_version
        version = match.group(1) #获取版本号
        if not self.is_allowed_version(version):
            raise exceptions.NotFound(self.invalid_version_message)
        return version
  1. 其它NamespaceVersioning(基于路由系统分发) , AcceptHeaderVersioning(基于Accept请求头)

对于内置的rest_framework reverse函数:

print(request.versioning_scheme.reverse(viewname='Myview',request=request)) #反向生成url
        #不用指定版本号是因为:重写的reverse函数已经把版本号赋值给kwargs:
        #    if request.version is not None:
        #    	kwargs = {} if (kwargs is None) else kwargs
        #   	kwargs[self.version_param] = request.version
        print(reverse(viewname='Myview', kwargs={'version': 'v2'})) #原生的reverse函数 需指定版本号
		'''
		output:
		http://127.0.0.1:8000/v1/Myview/
		/v2/Myview/
		'''
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐