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

Django 4.x中如何返回JSON格式的404和500错误而非默认HTML页面

解决DRF自定义异常处理器仍返回HTML页面的问题

核心原因

你的自定义异常处理器仅对DRF视图抛出的APIException子类异常生效,以下场景会触发Django原生异常逻辑,返回HTML页面:

  • 访问未配置的路由(Django全局404)
  • 使用普通Django视图而非DRF视图类
  • 底层异常未被DRF捕获(如数据库直接抛出的错误)

具体解决方案

1. 覆盖Django全局异常处理,统一返回JSON

在项目根目录新建error_views.py(或复用现有views.py),添加全局错误处理视图:

from django.http import JsonResponse

def json_404_handler(request, exception):
    return JsonResponse({"code": 404, "message": "请求的资源不存在"}, status=404)

def json_500_handler(request):
    return JsonResponse({"code": 500, "message": "服务器内部错误"}, status=500)

然后在项目根urls.py中覆盖默认错误路由:

from .error_views import json_404_handler, json_500_handler

handler404 = json_404_handler
handler500 = json_500_handler

2. 确保所有业务视图使用DRF视图类

普通Django视图不会触发DRF的异常处理器,需将视图改为继承APIView或DRF视图集:

from rest_framework.views import APIView
from rest_framework.response import Response

class BusinessView(APIView):
    def get(self, request):
        # 业务逻辑代码
        return Response({"data": "正常返回内容"})

3. 完善DRF异常处理器,捕获更多异常

修改exceptions.py,处理DRF未覆盖的Django原生异常:

from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
from django.core.exceptions import ObjectDoesNotExist

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

    # 处理DRF未捕获的异常
    if response is None:
        if isinstance(exc, ObjectDoesNotExist):
            return Response({"code": 404, "message": "指定资源不存在"}, status=status.HTTP_404_NOT_FOUND)
        # 其他未捕获异常统一返回500
        return Response({"code": 500, "message": "服务器内部错误"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    # 重写DRF已捕获异常的返回格式
    if response.status_code == 500:
        response.data = {"code": 500, "message": "服务器内部错误"}
    if response.status_code == 404:
        response.data = {"code": 404, "message": "请求的资源不存在"}
    
    return response

4. 强制DRF返回JSON格式

在settings.py中修改渲染器配置,优先返回JSON:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'backend.exceptions.custom_exception_handler',
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        # 若需要保留浏览器可查看的API调试页面,可保留下面一行
        # 'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:40:31