zoukankan      html  css  js  c++  java
  • drf模块及源码

    drf中的APIView请求生命周期

    APIView的as_view(局部禁用csrf) =>

    调用父类view中的as_view返回view()方法 =>

    自己的类调用自己的dispatch方法发送请求(drf的displatch中重写了错误分支,可以判断三大认证之前的错误,保证服务端请求安全,也可以判断逻辑中的错误) =>

    分发前完成request的二次封装,进行数据解析, =>

    三大认证 =>

    请求的实际响应(根据自己视图类的处理分发) =>

    其中出现异常,就会交给异常模块处理异常 =>

    响应模块完成响应 =>

    渲染模块将数据渲染称json或者浏览器的方式渲染.

    请求模块

    from rest_framework.request import Request
    class BookAPIView(APIView):
        def get(self, request, *args, **kwargs):
            return Response({
                'msg': 'apiview get ok'
            })
    
    • 将wsgi的request对象转换为drf的Request对象

    • 封装后的Requset对象完全兼容wsgi的request对象,并且将原request保存在新request._request中

      self._request = request

    • 重写格式化请求数据存放位置

      • 拼接参数:request.query_params

        def query_params(self):
            """
                More semantically correct name for request.GET.
                """
            return self._request.GET
        
      • 数据包参数:request.data

      • 参数分类更加规范,

    源码分析

    入口:APIView的dispatch方法的request=self.initialize_request(request, *args, **kwargs)

    获取解析类:parsers=self.get_parsers()

    进行局部全局默认配置查找顺序进行查找:return [parser() for parser in self.parser_classes]

    #drf中的Requset中的request的gteattr
    def __getattr__(self, attr):
        """
            If an attribute does not exist on this instance, then we also attempt
            to proxy it to the underlying HttpRequest object.
            """
        try:
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)
    

    解析模块

    检索顺序:局部配置 => 局部配置 => 框架默认配置

    局部配置

    在自己app包中的view视图文件中,添加

    from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
    class Cars(View):
        #局部配置解析类,使用于当前视图类
        paraser_class = [JSONParser,FormParser,MultiPartParser]
    
    全局配置

    settings中配置,如果有不用的,注释就好

    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',  #application/json
        'rest_framework.parsers.FormParser',  #urlencoded
        'rest_framework.parsers.MultiPartParser'  #form-data
    ],
    

    响应模块

    from rest_framework.response import Response
    def get(self, request, *args, **kwargs):
        # a
        response = Response(
            data={
                'msg': 'apiview get ok'
            },
            status=status.HTTP_404_NOT_FOUND,
        )
        print(response.data)
        return response
    
    源码
    class Response(SimpleTemplateResponse):
        """
        An HttpResponse that allows its data to be rendered into
        arbitrary media types.
        """
        def __init__(self, data=None, status=None,
                     template_name=None, headers=None,
                     exception=False, content_type=None):
    

    渲染模块

    局部配置

    在自己app包中的view视图文件中,添加

    from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class Cars(View):
        #局部配置渲染类,使用于当前视图类
        render_class = [JSONRenderer,BrowsableAPIRenderer]
    
    全局配置

    settings中配置,如果有不用的,注释就好

    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
    ],
    

    异常模块

    drf的异常处理只能处理客户端异常,自己重写一个文件用于捕获客户端以及服务端异常并显示或者保存到日志文件中.

    #首先在settings中配置异常捕获方法
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',
    	重写exception_handler方法:
    

    自定义异常处理文件

    # 一定要在settings文件中将异常模块配置自己的异常处理函数
    from rest_framework.views import exception_handler as drf_exception_handler
    from rest_framework.response import Response
    def exception_handler(exc, context):
        response = drf_exception_handler(exc, context)
        detail = '%s - %s - %s' % (context.get('view'), context.get('request').method, exc)
        if not response:  # 服务端错误
            response =  Response({'detail': detail})
        else:  #客户端错误,调用drf的异常处理方法
            response.data = {'detail': detail}
        # 核心:要将response.data.get('detail')信息记录到日志文件
        # logger.waring(response.data.get('detail'))
        return response
    
  • 相关阅读:
    收藏:详解交换机基础知识
    Linux Used内存到底哪里去了?
    TCP三次握手和四次挥手以及11种状态
    操作系统深度研究(75页PPT)
    命令行版的斗地主你玩过没?
    10大黑客专用的 Linux 操作系统
    (四)Linux命令大全:帮助命令
    (三)Linux命令大全:文件搜索命令
    (二)Linux命令大全:权限管理命令
    (一)Linux命令大全:文件处理命令
  • 原文地址:https://www.cnblogs.com/agsol/p/12093943.html
Copyright © 2011-2022 走看看