基于上述分析

   #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制
            self.initial(request, *args, **kwargs)
  #2.1处理版本信息
        #version代表版本  scheme代表版本管理的类  determine_version返回的是一个元祖
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

进入determine_version方法

    def determine_version(self, request, *args, **kwargs):
        """
        If versioning is being used, then determine any API version for the
        incoming request. Returns a two-tuple of (version, versioning_scheme)
        """
        #versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
        #如果我们没有配置版本控制类,将不做版本控制
        if self.versioning_class is None:
            return (None, None)

        #scheme就是版本控制的类
        #versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
        scheme = self.versioning_class()
        #返回版本 和版本控制的类
        return (scheme.determine_version(request, *args, **kwargs), scheme)

scheme.determine_version的执行取决与我们所引用的版本控制类是哪一个

Django rest framework  版本控制(源码分析)

这里以常用的URLPathVersioning类来说明

class URLPathVersioning(BaseVersioning):
    """
    To the client this is the same style as `NamespaceVersioning`.
    The difference is in the backend - this implementation uses
    Django's URL keyword arguments to determine the version.

    An example URL conf for two views that accept two different versions.

    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')
    ]

    GET /1.0/something/ HTTP/1.1
    Host: example.com
    Accept: application/json
    """
    invalid_version_message = _('Invalid version in URL path.')

    def determine_version(self, request, *args, **kwargs):
        #version_param  default_version DEFAULT_VERSION 都是在settings配置
        #version_param :url中获取值的key
        #default_version :默认版本
        #ALLOWED_VERSIONS:允许的版本
        version = kwargs.get(self.version_param, self.default_version)
        #如果version不存在,或者version不在允许访问的版本列表中
        if not self.is_allowed_version(version):
            #抛出异常
            raise exceptions.NotFound(self.invalid_version_message)
        #返回版本
        return version

is_allowed_version方法

 #判断是否能访问当前版本
    def is_allowed_version(self, version):
        if not self.allowed_versions:
            return True
        #version存在并且等于默认版本或者version在允许访问的版本中
        #返回True or Fasle
        return ((version is not None and version == self.default_version) or
                (version in self.allowed_versions))

到这里我们获取到了具体访问的版本和控制版本的类

回到最开始

 #2.1处理版本信息
        #version代表版本  scheme代表版本管理的类  determine_version返回的是一个元祖
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

我们将version 和scheme封装在request中如果我们访问的版本符合要求我们可以通过调用

request.version, request.versioning_scheme 来获得版本号和控制版本的类

 

 

BaseVersioning所有版本控制类都要继承的基类

class BaseVersioning(object):
    default_version = api_settings.DEFAULT_VERSION
    allowed_versions = api_settings.ALLOWED_VERSIONS
    version_param = api_settings.VERSION_PARAM

    def determine_version(self, request, *args, **kwargs):
        msg = '{cls}.determine_version() must be implemented.'
        raise NotImplementedError(msg.format(
            cls=self.__class__.__name__
        ))

    def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
        return _reverse(viewname, args, kwargs, request, format, **extra)

    #判断是否能访问当前版本
    def is_allowed_version(self, version):
        if not self.allowed_versions:
            return True
        #version存在并且等于默认版本或者version在允许访问的版本中
        #返回True or Fasle
        return ((version is not None and version == self.default_version) or
                (version in self.allowed_versions))
BaseVersioning

相关文章:

  • 2022-12-23
  • 2018-06-01
  • 2021-09-13
  • 2021-05-25
  • 2021-06-02
  • 2021-12-14
  • 2021-11-19
猜你喜欢
  • 2018-04-05
  • 2021-06-22
  • 2019-09-29
相关资源
相似解决方案