DRF基本视图——异常处理

核心结论在DRF视图中,抛出DRF的异常,DRF框架会自行捕获并构建响应返回!

思考:如果我想让drf框架,自行捕获非DRF异常,该怎么办呢?

异常捕获处理流程图示:

请求
路由分发
正常业务处理,构建响应(没有异常)
视图中产生异常
构建响应
浏览器
django服务器
视图函数
返回响应
调用异常处理函数
(1)、在DRF视图的处理过程中,由哪个函数处理异常的?

from rest_framework.views import exception_handler异常处理函数处理具体异常并构建响应,具体定义如下:

  • 功能:处理捕获的异常
  • exc:捕获到的异常对象
  • isinstance:用来判断一个对象的变量类型
  • 返回值:如果可以处理则返回响应对象,如果无法处理则返回None
# 该函数是DRF用来处理异常的函数
def exception_handler(exc, context):
    """
    Returns the response that should be used for any given exception.

    By default we handle the REST framework `APIException`, and also
    Django's built-in `Http404` and `PermissionDenied` exceptions.

    Any unhandled exceptions may return `None`, which will cause a 500 error
    to be raised.
    """
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    if isinstance(exc, exceptions.APIException):
        headers = {}
        if getattr(exc, 'auth_header', None):
            headers['WWW-Authenticate'] = exc.auth_header
        if getattr(exc, 'wait', None):
            headers['Retry-After'] = '%d' % exc.wait

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
        else:
            data = {'detail': exc.detail}

        set_rollback()
        return Response(data, status=exc.status_code, headers=headers)

		return None

总结上述DRF框架默认使用的异常处理函数,我们发现它只能处理APIExceptionHttp404PermissionDenied异常;除此以外的异常它无法处理。如下图,当异常为类型为ZeroDivisionError时,就会调用Django原生的异常处理函数进行抛出异常信息。
在这里插入图片描述

(2)、如果该函数无法处理非DRF异常,我们需要补充逻辑?

原则上我们不能直接修改源码来补充逻辑,而是通过自定义一个异常处理函数来实现;

新建BooksTest/exceptions.py文件,并自定义异常处理函数如下:

"""
自定义异常处理函数
"""
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from django.db import DatabaseError

# 该函数是DRF用来处理异常的函数
def exception_handler(exc, context):
    # 参数:exc捕获的异常对象
    # 处理得了返回一个响应,处理不了返回None
    # 1、把异常对象交给DRF的异常处理函数去处理
    response = drf_exception_handler(exc, context)
    if response:
        # response不为None,说明drf自行处理异常
        return response

    # 2、如果DRF异常处理函数无法处理,我们自行处理
    if isinstance(exc, ZeroDivisionError):
        return Response({'errmsg': '除数不能为零'})
    if isinstance(exc, DatabaseError):
        return Response({'errmsg': '数据库错误!'})

    return None

在配置文件中指定DRF的异常处理函数为我们自定义的函数:

REST_FRAMEWORK = {
    # ......
    # 自定义异常处理函数的导包路径
    'EXCEPTION_HANDLER': 'books_test.exceptions.exception_handler',
}
  • 再测试异常类型为ZeroDivisionError时,就会调用自定义的重写的DRF的异常处理函数:
  • 在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值