drf之版本

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在restful规范中要求,后端的API中需要体现版本。后端传递版本信息的方式主要有以下三种,其中URL中传递参数使用相对较多。

  • GET中传递参数
  • URL中传递参数【常用】
  • 请求头中传递参数

1、GET中传递参数

在这里插入图片描述

1.1 源码执行流程图

在这里插入图片描述

1.2 源码

1.2.1 QueryParameterVersioning(BaseVersioning)、BaseVersioning

class BaseVersioning:
    default_version = api_settings.DEFAULT_VERSION
    allowed_versions = api_settings.ALLOWED_VERSIONS    # 配置文件配置的允许版本列表
    version_param = api_settings.VERSION_PARAM          # 默认是version

    def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
        # 反向生成url,传入viewname和reqeust
        return _reverse(viewname, args, kwargs, request, format, **extra)

    def is_allowed_version(self, version):
        if not self.allowed_versions:
            return True
        return ((version is not None and version == self.default_version) or
                (version in self.allowed_versions)) # 结果为布尔值


class QueryParameterVersioning(BaseVersioning):

    invalid_version_message = _('Invalid version in query parameter.')

    def determine_version(self, request, *args, **kwargs):
        version = request.query_params.get(
            self.version_param, 
            self.default_version
            )
        if not self.is_allowed_version(version):
            raise exceptions.NotFound(self.invalid_version_message)
        return version

1.2.2 HomeView(APIView)、APIView(View)

class APIView(View):    

    def determine_version(self, request, *args, **kwargs):

        if self.versioning_class is None:
            return (None, None)
        scheme = self.versioning_class()    # 类对象
        # (v1, <rest_framework.versioning.URLPathVersioning object at 0x0000023A92344820>)
        return (scheme.determine_version(request, *args, **kwargs), scheme) 


    def initial(self, request, *args, **kwargs):  
        # 获取version及scheme,并赋值给request.version, request.versioning_scheme 
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme


    def dispatch(self, request, *args, **kwargs):
        # 第一步:封装request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
            self.initial(request, *args, **kwargs)

            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

class HomeView(APIView):
    versioning_class = QueryParameterVersioning
    # versioning_class = URLPathVersioning
    # versioning_class = AcceptHeaderVersioning

    def get(self, request, *args, **kwargs):
        print(request.version)
        print(request.versioning_scheme)
        # 反向生成url
        print(request.versioning_scheme.reverse(viewname='hh', request=request))
        return Response('ok')

2、URL中传递参数【常用】

在这里插入图片描述
源码执行流程及源码不再详述。

3、请求头中传递参数

在这里插入图片描述
源码执行流程及源码不再详述。

4、反向生成URL

在每个版本处理的类中还定义了reverse方法,是用来反向生成URL并携带相关的的版本信息用的。
在这里插入图片描述

以URLPathVersioning(BaseVersioning)为例,源码分析如下:

class URLPathVersioning(BaseVersioning):

	# 注意:reverse方法须传入两个参数,viewname,request
    def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
        if request.version is not None:
            kwargs = {} if (kwargs is None) else kwargs
            kwargs[self.version_param] = request.version

        return super().reverse(
            viewname, args, kwargs, request, format, **extra
        )
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值