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]
posted @ 2019-11-22 20:09  corei5tj  阅读(146)  评论(0编辑  收藏  举报