Django全局异常处理全攻略

在 Django 中处理全局异常,有几种常见的方式,通常目标是:

  • 捕获项目中未被单独处理的错误
  • 统一返回给前端(如 JSON 响应 / 自定义错误页)
  • 方便记录日志

1. 使用 Django 自带的全局异常处理机制

Django 有一些内置的全局错误视图(默认在 django.views.defaults 中):

  • 404 错误:handler404
  • 500 错误:handler500
  • 403 错误:handler403
  • 400 错误:handler400

你可以在项目的 urls.py 中进行重写:

python 复制代码
# urls.py
from django.conf.urls import handler404, handler500, handler403, handler400
from django.http import JsonResponse

def custom_404(request, exception):
    return JsonResponse({"error": "页面未找到"}, status=404)

def custom_500(request):
    return JsonResponse({"error": "服务器错误"}, status=500)

def custom_403(request, exception):
    return JsonResponse({"error": "无权限访问"}, status=403)

def custom_400(request, exception):
    return JsonResponse({"error": "错误请求"}, status=400)

handler404 = custom_404
handler500 = custom_500
handler403 = custom_403
handler400 = custom_400

👉 适合处理 HTTP 层面的全局错误。


2. 使用中间件捕获全局异常

如果你想在 更底层 捕获异常,可以写一个自定义中间件:

python 复制代码
# middlewares.py
import logging
from django.http import JsonResponse

logger = logging.getLogger(__name__)

class GlobalExceptionMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            return self.get_response(request)
        except Exception as e:
            logger.error(f"Unhandled Exception: {str(e)}", exc_info=True)
            return JsonResponse({"error": "服务器内部错误"}, status=500)

然后在 settings.py 中注册:

python 复制代码
MIDDLEWARE = [
    ...
    'your_project.middlewares.GlobalExceptionMiddleware',
]

👉 适合捕获 所有未被显式处理的异常,并进行日志记录 / 统一 JSON 响应。


3. Django REST Framework (DRF) 的全局异常处理

如果你用的是 DRF,可以在 settings.py 中配置全局异常处理函数:

python 复制代码
# settings.py
REST_FRAMEWORK = {
    "EXCEPTION_HANDLER": "your_project.utils.custom_exception_handler"
}

实现 custom_exception_handler:

python 复制代码
# utils.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status

def custom_exception_handler(exc, context):
    # 先调用 DRF 默认的异常处理
    response = exception_handler(exc, context)

    if response is None:
        # 没有被 DRF 识别的异常
        return Response({"error": "服务器内部错误"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    # 可以统一改造返回结构
    return Response({
        "error": response.data,
        "status_code": response.status_code
    }, status=response.status_code)

👉 适合 API 项目,能让前端统一处理错误。


4. 日志系统与监控

全局异常捕获后,还需要考虑 记录日志 和 报警。常见做法:

  • 在中间件或异常处理函数里调用 logging,写到文件或 ELK。
  • 接入 Sentry,实时监控线上异常。

✅ 总结:

  • 普通 Django 项目:用 handler404/500/403/400 + 中间件。
  • API 项目(DRF):用 自定义 exception_handler。
  • 日志监控:结合 logging 或 Sentry。
相关推荐
曲径海盗1 小时前
【Python 学习第 41 天】for 循环
python·学习笔记·编程入门
摇滚侠1 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
沧海一笑-dj1 小时前
【Python】Python学习笔记-模块与包
python·pip·模块·包·python包·python模块·包与模块
echome8881 小时前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
云和数据.ChenGuang1 小时前
Python 单继承与多继承深度剖析:从 MRO 到实战取舍
开发语言·人工智能·python·langchain
威哥爱编程1 小时前
Python 智能体开发实战 02:你的 AI 助教说话像换了个模型?九成的 system prompt 都写错了
python·agent
威哥爱编程1 小时前
Python 智能体开发实战 01:装了三遍环境还在报错?虚拟环境和 DeepSeek 一次配到位
python·agent
小咕聊编程2 小时前
基于Python的豆瓣电影数据可视化系统构建分析
开发语言·python·信息可视化
小小张说故事3 小时前
Python 的 dict 为什么查询是 O(1)?拆开哈希表、扰动函数与扩容阈值
python
像风一样的男人@4 小时前
python --基于scp的文件传输助手
开发语言·python