千家信息网

如何使用Django与DRF实现全局异常处理方案

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,小编给大家分享一下如何使用Django与DRF实现全局异常处理方案,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!实现的目标
千家信息网最后更新 2026年11月01日如何使用Django与DRF实现全局异常处理方案

小编给大家分享一下如何使用Django与DRF实现全局异常处理方案,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

实现的目标

如果没有 DRF,我们只需要在 Django 中加一个中间件就可以解决全局异常的处理问题,但是 DRF 会帮我们处理一些异常并自动返回到客户端,因此我们要协调两者的异常处理策略。

同时我们希望能使用 Django 的 admin 进行一些后台的数据查看和修改,因此最好要保留 admin 的内部异常处理行为。

本文的目标如下:

  • 保留 Django 自带的 admin 的异常处理行为

  • 拦截 DRF 的异常并进行全局异常行为处理

  • 拦截除 DRF 的异常之外的其他 Django 异常并进行全局异常行为处理

DRF 全局异常拦截的解决思路

首先 DRF 的异常都是继承自 APIException 这个类的,并且 DRF 跑出的异常会被 exception_handler 这个异常处理函数拦截(这个函数的位置在 /python3.7/site-packages/rest_framework/views.py中)。

我们进一步查看这个函数的源码:

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 会处理所有继承自 APIException 的异常类,并且还会额外的处理 Django 内置的 Http404 和 PermissionDenied 异常,并将这些异常的处理结果返回到前台。

如果不再这些处理范围之内,函数会返回 None,这时候会给 Django 抛出一个 500 的服务器错误异常。

DRF 支持单独配置异常处理函数,因此第一步现在 setting 中指定自定义的异常处理函数的位置:

REST_FRAMEWORK = {    'EXCEPTION_HANDLER': 'server.exception.exception_globe.globe_exception_handler'}

然后我们定义自己的异常处理程序:

第一步,调用 DRF 自己的异常处理函数第二步,对 DRF 拦截的异常进行处理第三步,将其他异常抛给 Django 处理

def globe_exception_handler(exc, context):    """        Below is the global exception handler of drf        Http404 / PermissionDenied / APIException    """    # Call REST framework's default exception handler    response = exception_handler(exc, context)    request = context['request']    # Exceptions form DRF and Django built-in `Http404` and `PermissionDenied`    if response is not None:        if isinstance(response.data, list):            msg = '; '.join(response.data)        elif isinstance(response.data, str):            msg = response.data        else:            msg = 'Sorry, we make a mistake (* ̄︶ ̄)!'        ex_data = {            "msg": msg,            "error_code": 1000,            "request": request.path        }        return JsonResponse(data=ex_data, status=response.status_code)    # Exceptions from others    # 如果 response 为 None 则直接触发上面的 ExceptionGlobeMiddleware    return response

Django 异常处理方案

从上一步的结果我们知道,DRF 处理不了的异常我们抛给了 Django,而 Django 支持通过定义中间件进行全局异常处理,因此接下来我们只需要定一个 Django 全局异常处理的中间件,并将中间件配置到 setting 文件中的 MIDDLEWARE 数组即可。

try:    from django.utils.deprecation import MiddlewareMixin  # Django 1.10.xexcept ImportError:    MiddlewareMixin = object  # Django 1.4.x - Django 1.9.xclass ExceptionGlobeMiddleware(MiddlewareMixin):    """        Below is the global exception handler of django    """    def process_exception(self, request, exception):        # 直接抛出 django admin 的异常        if str(request.path).startswith('/admin/'):            return None        # 捕获其他异常,直接返回 500        ex_data = {            "msg": "Sorry, we make a mistake (* ̄︶ ̄)!",            "error_code": 1000,            "request": request.path        }        return JsonResponse(data=ex_data, status=500)

值得注意的是,我们可以在中间件的处理函数中拿到 request 对象,因此,我们可以通过这个对象拿到用户请求的 url,这样,我们通过判断 url 就可以得到那些请求是来自 Django 自带的 admin 的。

参考代码如下:

# 直接抛出 django admin 的异常if str(request.path).startswith('/admin/'):    return None

以上是"如何使用Django与DRF实现全局异常处理方案"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

处理 函数 全局 中间件 行为 方案 篇文章 位置 内容 对象 目标 结果 并将 参考 支持 配置 接下来 不怎么 中指 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 河南云网互联网络科技有限公司 苏州找大状互联网科技有限公司 互联网科技会 互联网巨头科技公司 朗新科技与工业互联网 没上市的科技互联网公司 互联网的科技创新 互联网科技小贷 西安互联网科技公司 广州善班互联网科技 一五八零互联网科技 佰商互联网科技有限公司 江苏南京365互联网科技 重庆互联网医院沙龙医盟信息科技 互联网科技公司营业执照怎么办理 互联网时代的科技公司 电子商务与互联网科技的关系 江苏互联网智能科技产品出厂价 亚光科技低轨卫星互联网 现代互联网科技公司 苏州互联网科技贷款公司 互联网科技的未来发展 太原新华互联网科技学校怎么样 青岛中康互联网医疗科技有限公司 恒银科技与互联网金融 黑科技闪耀互联网之光 湖南一路畅行互联网科技 玉溪新华互联网科技怎么选 上海互联网科技园景观 互联网科技创业有什么好项目
0