在 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。