zoukankan      html  css  js  c++  java
  • 04 drf源码剖析之版本

    04 drf源码剖析之版本

    1. 版本简述

    • API版本控制使您可以更改不同客户端之间的行为。REST框架提供了许多不同的版本控制方案。

    • 版本控制由传入的客户端请求确定,并且可以基于请求URL或基于请求标头。

    • 启用API版本控制后,该request.version属性将包含一个字符串,该字符串与传入客户端请求中请求的版本相对应。

    • 默认情况下,版本控制未启用,并且request.version将始终返回None

    2. 版本使用

    1. settings配置文件

      REST_FRAMEWORK = {
          'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
       'ALLOWED_VERSIONS':['v1','v2'],
          
      }
      
    2. 路由

      # 路由分发
      urlpatterns = [
          url(r'^api/(?P<version>w+)/', include('api.urls')),
      ]
      
      # 子路由
      urlpatterns = [
          url(r'^order/$', views.OrderView.as_view()),
      ]
      
    3. 通过request.version可以取值

      from rest_framework.views import APIView
      from rest_framework.response import Response
      from rest_framework.request import Request
      
      class OrderView(APIView):
          def get(self,request,*args,**kwargs):
              print(request.version)
              print(request.versioning_scheme)
              return Response('...')
      
          def post(self,request,*args,**kwargs):
              return Response('post')
      

    3.源码剖析

    • 请求到来执行dispatch方法

      class APIView(View):
          versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
          
      	def dispatch(self, request, *args, **kwargs):
             
              # 第一步 
              self.args = args
              self.kwargs = kwargs
      
              """
              request = 生成了一个新的request对象,此对象的内部封装了一些值。
              request = Request(request)
                  - 内部封装了 _request = 老的request
              """
              request = self.initialize_request(request, *args, **kwargs)
              self.request = request
      
              self.headers = self.default_response_headers  # deprecate?
      
              try:
                  # 第二步
                  self.initial(request, *args, **kwargs)
      
                  执行视图函数...
      
    • 执行initial方法

      def initial(self, request, *args, **kwargs):
             
          # 2.1 处理drf的版本
          version, scheme = self.determine_version(request, *args, **kwargs)
          request.version, request.versioning_scheme = version, scheme
      		...
      
    • determine_version

      • versioning_class是在配置文件设置的URLPathVersioning
      def determine_version(self, request, *args, **kwargs):
          if self.versioning_class is None:
              return (None, None)
          scheme = self.versioning_class() # obj = XXXXXXXXXXXX()
          return (scheme.determine_version(request, *args, **kwargs), scheme)
      
    • 接着去执行URLPathVersioning对象的determine_version方法

      class URLPathVersioning(BaseVersioning):
          """
          urlpatterns = [
              url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
             
          ]
          """
          invalid_version_message = _('Invalid version in URL path.')
      
          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
      
      
      

    4. 总结

    1. 请求过来执行dispatch方法中的initial方法中的版本处理的determine_version方法
    2. 找到setings配置中版本类URLPathVersioning,对其实例化,
    3. 执行实例化对象的determine_version方法,
    4. 该方法会获取路由中输入的版本信息,
    5. 在is_allowed_version方法中会判断url中的版本是否在settings配置设定的ALLOWED_VERSIONS列表中
    6. 如果在就将版本赋值给request.version,将版本类赋值给request.versioning_scheme
  • 相关阅读:
    常用第三方快递鸟单号查询Api接口免费对接调用攻略
    Solution -「CF 1477A」Nezzar and Board
    Solution -「THUPC 2021」区间矩阵乘法
    Solution Set -「CF 1520」
    Solution -「HNOI 2010」城市建设
    Solution -「NOI 2007」货币兑换
    Solution -「洛谷 P6156」简单题
    Solution -「YunoOI 2017」由乃的 OJ
    Journey -「CQOI 2021」
    Note -「SOS DP」高维前缀和
  • 原文地址:https://www.cnblogs.com/liubing8/p/11939525.html
Copyright © 2011-2022 走看看