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
  • 相关阅读:
    jquery toggle(listenerOdd, listenerEven)
    struts quick start
    hdu 1518 Square (dfs)
    hdu 2544 最短路 (最短路径)
    hdu 1754 I Hate It (线段树)
    hdu 1856 More is better (并查集)
    hdu 1358 Period (KMP)
    hdu 2616 Kill the monster (DFS)
    hdu 2579 Dating with girls(2) (bfs)
    zoj 2110 Tempter of the Bone (dfs)
  • 原文地址:https://www.cnblogs.com/liubing8/p/11939525.html
Copyright © 2011-2022 走看看