zoukankan      html  css  js  c++  java
  • drf源码分析系列---版本控制

    版本的使用

    第一步:写路由url(r'^api/(P<version>w+)/user/$',views.UserView.as_view()),
    第二步:写模块导入from rest_framework.versioning import URLPathVersioning
    第三步:写视图 可不写
    request.version获取版本号
    class UserView(APIView):  # DEFAULT_VERSIONING_CLASS在APIView中默认配置
        def get(self,request,*args,**kwargs):
            print(request.version)
            return Response('....')
    第四步:写settings配置:
    REST_FRAMEWORK = {
        "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",  #配置全局的版本信息
        "ALLOWED_VERSIONS":['v1','v2']    #配置允许版本号范围
    
    }
    

    版本的源码分析

    执行流程

    1.请求进来执行dispatch方法中的initialize_request方法
        def initialize_request(self, request, *args, **kwargs):
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    #会对request对象进行重新封装,把老的request封装成新的request
    
    2.接着执行initial方法
        def initial(self, request, *args, **kwargs):
    		.......略过的代码,暂时与版本无关
    
            
            #版本相关的函数
            version, scheme = self.determine_version(request, *args, **kwargs)  
            request.version, request.versioning_scheme = version, scheme
    
            self.perform_authentication(request)
            self.check_permissions(request)
            self.check_throttles(request)
    
    3.执行determine_version方法
        def determine_version(self, request, *args, **kwargs):
            if self.versioning_class is None:
                return (None, None)
            scheme = self.versioning_class()
            return (scheme.determine_version(request, *args, **kwargs), scheme)
        
    #会调用versioning_class进行判断,默认为None,版本也就返回None,自我认为意义不大,version_class先去自己定义的类中找该方法,如果没有定义就去父类中找,父类中为None
    
    4.如果自己的定义的版本类中有该方法,就执行scheme = self.versioning_class(),对自己定义的版本类进行实例化
    
    5.执行determine_version返回值中的scheme.determine_version(request, *args, **kwargs)
    #这个scheme就是我们写的版本类
    
    6.执行自定义的版本类中的determine_version
        def determine_version(self, request, *args, **kwargs):
            version = kwargs.get(self.version_param, self.default_version)
            if version is None: #判断version如果为None就会设置成默认的版本
                version = self.default_version
    
            if not self.is_allowed_version(version):#对版本号进行限制allowed_version,在settings中定义ALLOWD_VERSION=[V1,V2]
                
                raise exceptions.NotFound(self.invalid_version_message)
            return version
        
    # version_param就是一个字符串version,也就是URL中的版本号
    
    7.限制版本号的函数
        def is_allowed_version(self, version):
            if not self.allowed_versions:# --->ALLOWD_VERSION=[V1,V2]
                return True
            return ((version is not None and version == self.default_version) or
                    (version in self.allowed_versions))
    

    概括

    1.当请求进来时,先执行dispatch方法,执行initialize_request对request进行重新的封装
    2.执行initial方法,执行版本相关函数:determine_version(request, *args, **kwargs)
    3.在determine_version方法中,会调用versioning_class进行判断,默认为None,版本也就返回None,意义不大
    4.version_class先去自己定义的类中找该方法,如果没有定义就去父类中找,父类中为None
    5.如果自己的定义的版本类中有该方法,就会执行scheme = self.versioning_class()进行实例化
    6.接着就会执行返回值中的scheme.determine_version,scheme指的就是版本类
    7.执行认证类中的determine_version方法..
              version = kwargs.get(self.version_param, self.default_version)
              version_param就是一个字符串version,也就是URL中的
    8.接着会判断version如果为None就会设置成默认的版本
    9.对版本号进行限制allowed_version,在settings中定义ALLOWD_VERSION=[V1,V2]
    
  • 相关阅读:
    js18
    js17
    js16
    js15
    js14
    js13
    js12
    js11
    八月二十三的php
    八月二十二的php
  • 原文地址:https://www.cnblogs.com/tangjian219/p/11913826.html
Copyright © 2011-2022 走看看