You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用DRF响应替换Django默认404等错误页面?

刚好我之前也遇到过这个问题,给你一套完整的落地方案,一步步来就能解决:

第一步:编写自定义异常处理函数

首先,在你的项目根目录(或者专门的utils文件夹)新建一个exceptions.py文件,用来处理DRF和Django原生的异常,转换成统一的DRF响应格式:

from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404, HttpResponseForbidden

def custom_exception_handler(exc, context):
    # 先调用DRF自带的异常处理器,处理APIView抛出的异常
    response = exception_handler(exc, context)

    # 如果DRF没处理(比如Django原生路由的404),我们手动转换
    if response is None:
        # 处理原生404
        if isinstance(exc, Http404):
            return Response(
                {"detail": "资源不存在"},
                status=status.HTTP_404_NOT_FOUND
            )
        # 处理原生权限拒绝
        elif isinstance(exc, HttpResponseForbidden):
            return Response(
                {"detail": "权限不足"},
                status=status.HTTP_403_FORBIDDEN
            )
        # 后续要覆盖其他错误(比如500),直接在这里加判断就行

    # 统一DRF异常的响应格式(确保返回的JSON里有detail字段)
    if response is not None and "detail" not in response.data:
        response.data = {"detail": response.data}

    return response
第二步:配置DRF使用自定义处理器

打开项目的settings.py,找到REST_FRAMEWORK配置块(如果没有就新建),指定我们的异常处理器路径:

REST_FRAMEWORK = {
    # 其他DRF配置(比如分页、认证)...
    'EXCEPTION_HANDLER': '你的项目名称.exceptions.custom_exception_handler',
}

注意把你的项目名称改成你实际的项目根目录名字(比如myproject)。

第三步:解决Debug=True时的500和原生404问题

当DEBUG=True时,Django会默认显示调试页面,拦截了我们的DRF响应。这时候需要修改项目根目录的urls.py,替换默认的错误处理器:

from django.conf import settings
from django.conf.urls import handler404, handler500
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from .exceptions import custom_exception_handler

# 自定义404视图,用DRF格式返回
def drf_404(request, exception=None):
    return custom_exception_handler(Http404(), {"request": request})

# 自定义500视图,用DRF格式返回
def drf_500(request):
    return Response(
        {"detail": "服务器内部错误"},
        status=status.HTTP_500_INTERNAL_SERVER_ERROR
    )

# 只有Debug模式下才替换,避免影响生产环境的错误页面配置(如果有的话)
if settings.DEBUG:
    handler404 = drf_404
    handler500 = drf_500
第四步:验证效果
  • 当DEBUG=True时,访问不存在的路由,会返回DRF标准的JSON响应,而不是Django的调试页面;500错误也会返回JSON格式。
  • 当DEBUG=False时,访问不存在的路由,同样会返回DRF的JSON响应,替代原来的HTML 404页面。

后续如果要覆盖其他错误(比如400参数错误、401未认证),只需要在custom_exception_handler里添加对应的异常判断即可,比如处理rest_framework.exceptions.ValidationError这类DRF内置异常。

内容的提问来源于stack exchange,提问作者Piotr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:36:32