zoukankan      html  css  js  c++  java
  • drf 版本解析

    版本

    使用(局部)

    • url中写version

      url(r'^order/(?P<version>[v1|v2]+)/$', views.OrderView.as_view()),
      
      
    • 在视图中应用

      from rest_framework.views import APIView
      from rest_framework.response import Response
      from rest_framework.request import Request
      from rest_framework.versioning import URLPathVersioning
      
      
      class OrderView(APIView):
      
          versioning_class = URLPathVersioning	# 引用版本类
          def get(self,request,*args,**kwargs):
              print(request.version)
              print(request.versioning_scheme)
              return Response('...')
      
          def post(self,request,*args,**kwargs):
              return Response('post')
      
    • 在settings中配置

      REST_FRAMEWORK = {
          "PAGE_SIZE":2,
          "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination",
          "ALLOWED_VERSIONS":['v1','v2'],
          'VERSION_PARAM':'version'
      }
      

    使用(全局)推荐

    • url中写version

      url(r'^order/(?P<version>[v1|v2]+)/$', views.OrderView.as_view())
      
      url(r'^order/(?P<version>w+)/$', views.OrderView.as_view()),
      
    • 在视图中应用

      from rest_framework.views import APIView
      from rest_framework.response import Response
      from rest_framework.request import Request
      from rest_framework.versioning import URLPathVersioning
      
      
      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')
      
    • 在settings中配置

      REST_FRAMEWORK = {
      
          "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
          "ALLOWED_VERSIONS":['v1','v2'],
          'VERSION_PARAM':'version'
      }
      

    源码分析

    class APIView(View):
        versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
        
    	def dispatch(self, request, *args, **kwargs):
           
            # ###################### 第一步 ###########################
            """
            request,是django的request,它的内部有:request.GET/request.POST/request.method
            args,kwargs是在路由中匹配到的参数,如:
                url(r'^order/(d+)/(?P<version>w+)/$', views.OrderView.as_view()),
                http://www.xxx.com/order/1/v2/
            """
            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)
    
                执行视图函数。。
    	
    	def initial(self, request, *args, **kwargs):
           
            # ############### 2.1 处理drf的版本 ##############
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    		...
            
        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)
            
    

    版本类:

    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
    #  ================    
        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))
    
    

    流程分析:

    - 请求到来时,会执行APIView类的dispatch方法,先进行属性的封装;
    - 执行initial方法,里面先进行版本的处理:
    - 会执行determine_version()方法,会获取versioning_class的类URLPathVersioning, 
    - 实例化URLPathVersioning类,然后执行URLPathVersioning类中的determine_version()方法,
    - 通过kwargs.get()获取版本信息v1,如果没有,返回None;通过kwargs.get()获取版本信息v1,如果没有,返回None;
    - allowed_version获取配置中版本列表,
    然后判断获取到的版本信息是否在列表中,存在,返回version。
    
  • 相关阅读:
    C++基础学习1-编译与链接
    html学习
    使用BP拦截POST请求包
    2019.9.17
    搭建LAMP环境
    2019.9.16
    2019.9.12
    2019.9.11
    手脱无名壳tslgame_rl
    一款自制壳的脱壳
  • 原文地址:https://www.cnblogs.com/yzm1017/p/11945833.html
Copyright © 2011-2022 走看看