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
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
  • 原文地址:https://www.cnblogs.com/2222bai/p/12093804.html
Copyright © 2011-2022 走看看