• drf 异常模块+响应模块


    一、drf异常模块源码分析(重点)

    • 在APIView的dispatch方法中,有一个超大的try...except...,将代码运行异常都交给异常处理模块处理self.handle_exception(exc)方法
    • 从配置中映射出配置处理异常的函数(自定义异常模块就是自定义配置指向自己的函数):self.get_exception_handler()方法-> return self.settings.EXCEPTION_HANDLER,通过settings获取了异常处理的方法
    • 默认的异常函数在和源码的APIView类相同的views文件中
    • exception_handler(exc, context)处理异常:
      • 如果异常错误是404,或APIException这个基类中的就处理,否则就之间返回None

    注:一般异常模块我们需要重写,因为当项目上线时,我们需要捕获并记录项目运时出现的异常信息,方便修改

    二、自定义配置drf异常模块

    • 在settings文件的配置中配置EXCEPTION_HANDLER,指向自定义的exception_handler函数
    • 当drf出现异常了,都会回调exception_handler函数,携带 异常对象和异常相关信息内容,在exception_handler函数完成异常信息的返回以及异常信息的logging日志
    '''settings.py配置'''
    REST_FRAMEWORK = {
        # 异常模块,二选一即可
        'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',	# 源码的异常处理函数
        # 'EXCEPTION_HANDLER': 'api.utils.exception.exception_handler',	# 自定义的异常处理函数
    }   
    
    '''exception.py'''
    
    from rest_framework.response import Response
    from rest_framework.views import exception_handler as drf_exception_handler
    from rest_framework import status 
    
    def exception_handler(exc, context):
        response = drf_exception_handler(exc, context)
    
        if response is None: # drf没有处理的异常(服务器异常)
            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data={
                'status': 7,
                'exc': '%s' % exc
            })
    
        # 项目阶段,要记录到日志文件
        return Response(status=response.status_code, data={
            'status': 7,
            # drf处理的客户端异常,原始处理方式是将异常信息放在response对象的data中,data的格式是{'datail': '具体的异常信息'}
            'exc': '%s' % response.data.get('detail')
        })
    

    三、drf响应模块

    • drf响应模块就是Response类,Response类实例化产生对象就是返回响应信息和响应状态码等。
    • 因此响应模块的源码只需要看Response类的__init__方法就可以了
    def __init__(self, data=None, status=None,template_name=None, headers=None,
                 exception=False, content_type=None):
    '''
    # data: 是返回的信息。当出现异常时,drf的异常处理函数都将异常信息封装成{'detail': exc.detail}
    
    # status: 响应状态码。
    
    # headers: 响应头信息
    
    # exception: 标识异常是否发生,随便你写不写。没啥区别
    
    # content_type: 响应类型。默认是json。drf也只能返回json格式数据
    '''
    

    3.1 二次封装Response

    from rest_framework.response import Response
    
    class APIResponse(Response):
        def __init__(self, data_status=0, msg="ok", results=None, http_status=200, headers=None, exception=False, **kwargs):
            # 格式化data
            data = {    # json的response基础有数据状态码和数据状态信息
                "status":data_status,
                "msg":msg
            }
            if results is not None: # 后台有数据,响应数据
                data["results"] = results
            data.update(**kwargs)   # 后台的一切自定义响应数据直接放到响应数据data中
            super().__init__(data=data, status=http_status, headers=headers, exception=exception)
    
  • 相关阅读:
    【LeetCode】70. 爬楼梯
    C++Socket编程—socket网络模型之IOCP
    leetcode_买卖股票_dp状态机
    leetcode_买卖股票_暴力递归
    tensorflow正则化
    程序员掌握这些面试技巧,成功上岸!
    阶段二Linux 高级编程:Linux基础命令三019
    阶段二Linux 高级编程:Linux基础命令二018
    阶段二Linux 高级编程:Linux基础命令一017
    阶段一Python核心编程:面向对象版学员管理系统016
  • 原文地址:https://www.cnblogs.com/XuChengNotes/p/11893229.html
Copyright © 2020-2023  润新知