zoukankan      html  css  js  c++  java
  • Day 71 drf五大模块(second day)

    APIview请求生命周期

    APIview的as_view类(局部禁用csrf) ---> 走父级的as_view调用dispatch分发请求 ---> APIview自己重写了dispatch,使用自己完成分发 ---> 分发前完成request二次封装,数据解析 ---> 三大认证 ---> 请求的实际响应 ---> (自己的视图类的处理分发) ---> 出现了异常,就会交给异常模块处理异常 ---> 响应模块完成响应,渲染模块可以json或浏览器两种方式渲染

    请求模块

    """
    dispatch ---> initialize_request ---> Request
        
    """
    # dispatch中
    request = self.initialize_request(request, *args, **kwargs)
    
    # initialize_request返回initial request object
    def initialize_request(self, request, *args, **kwargs):
            # 返回一个字典
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    
    # Request类中会将wsgi的request赋值给drf的request对象   
    self._request = request
    
    @property
    def query_params(self):   
        return self._request.GET
    
    """
    源码分析
    print(request._request.method)  # 在内部将wsgi的request赋值给request._request
    print(request.method)  # 就是通过Request类里__getattr__走的是request._request.method
    print(request.query_params)  # 走的是方法属性,就是给request._request.GET重新命名(property装饰器)
    print(request.data)  # 走的是方法属性,值依赖于request._full_data(property装饰器)
    """
    

    解析模块

    """
    dispatch ---> initialize_request的get_parsers ---> 遍历返回parser_classes并执行 ---> api_settings.DEFAULT_PARSER_CLASSES
    
    """
    
    REST_FRAMEWORK = {
        # 全局配置解析类:适用于所有视图类
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ],
    }
    
    """
    源码分析:
    入口:APIVIew的dispatch方法的 request=self.initialize_request(request, *args, **kwargs)
    获取解析类:parsers=self.get_parsers(),
    进行局部全局默认配置查找顺序进行查找:return [parser() for parser in self.parser_classes]
    """
    

    响应模块

    """
    Response类
    data: 响应数据
    status: 响应的网络状态码
    -------------------
    template_name: drf完成前后台不分离返回页面,但是就不返回data(了解)
    headers: 响应头,一般不规定,默认(了解)
    exception: 一般异常响应,会将其设置成True,默认False(了解)
    content_type: 默认就是 application/json, 不需要处理
    """
    

    渲染模块

    """
    局部配置:renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
    	全局配置:
    	RESR_FRAMEWORK = {
    		'DEFAULT_RENDERER_CLASSES': [
            	'rest_framework.renderers.JSONRenderer',
            	# 'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
        	]
    	}	
    """
    

    异常模块

    """
    dispatch ---> handle_exception ---> 
    
    
    """
        def handle_exception(self, exc):
            if isinstance(exc, (exceptions.NotAuthenticated,
                                exceptions.AuthenticationFailed)):
                # WWW-Authenticate header for 401 responses, else coerce to 403
                auth_header = self.get_authenticate_header(self.request)
    
                if auth_header:
                    exc.auth_header = auth_header
                else:
                    exc.status_code = status.HTTP_403_FORBIDDEN
    
            # 获取exception_handler方法
            exception_handler = self.get_exception_handler()
    
            context = self.get_exception_handler_context()
            # 执行views.py中的exception_handler方法
            response = exceptio n_handler(exc, context)
    
            if response is None:
                self.raise_uncaught_exception(exc)
    
            response.exception = True
            return response
    
    

    二次封装exception_handler方法

    # 一定要在settings文件中将异常模块配置自己的异常处理函数
    from rest_framework.views import exception_handler as drf_exception_handler
    from rest_framework.response import Response
    
    def exception_handler():
        response = drf_exception_handler(exc, context)
        detail = %s + %s + %s % (context.get('view'), context.get('request').method, exc)
        if not response:
            # 原生exception_handler不会再返回None了
            response = Response({'detail': detail})
        else:
            response.data = {'detail': detail}
            # 核心: 要将request.data.get('detail')信息记录到日志文件
            # logger.waring(response.data.get('detail'))
        return response
    
  • 相关阅读:
    三分法
    string常用函数的整理
    一句话 讲解 kmp的 next 数组 看不懂的 直接来掐死我吧
    http://www.codeforces.com/contest/703/problem/D D. Mishka and Interesting sum (莫队的TLE)
    Codeforces Round #365 (Div. 2) C
    数论
    默慈金数
    转载:HTTP 请求头中的 X-Forwarded-For
    Glusterfs volume 的三种挂载方式
    GlusterFS 配置及使用
  • 原文地址:https://www.cnblogs.com/2222bai/p/12093804.html
Copyright © 2011-2022 走看看