• (四) rest_framework 版本控制源码


    流程:

    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/
    		'''
    
  • 相关阅读:
    C/C++指针精髓转载
    彻底搞定c指针系列转载
    vc根据域名获取IP地址 gethostbyname()函数
    try catch finally的执行顺序
    vc2008中mfc字符串转换待续
    C++字符串完全指引(二)转载
    vc随机字符串
    C++字符串完全指引转载
    编写c++程序的优良习惯
    ReportViewer一些技巧
  • 原文地址:https://www.cnblogs.com/donghaoblogs/p/12443025.html
Copyright © 2020-2023  润新知