如何用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
相关产品推荐
相关产品推荐

