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

如何在Django REST Framework中自定义验证错误响应?

解决DRF统一验证错误响应格式问题

你的自定义异常处理器未达到预期,核心原因是没有针对性处理JWT这类特殊异常的结构,同时常规错误的转换逻辑可以优化。以下是修正后的完整实现方案:

步骤1:完善自定义异常处理器

from rest_framework.views import exception_handler
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError

def custom_exception_handler(exc, context):
    # 先调用DRF默认处理器获取基础响应
    response = exception_handler(exc, context)
    
    if response is not None:
        custom_response = {
            "status": False,
            "responseCode": 0,
            "message": "Validation error",
            "data": {}
        }
        
        # 单独处理JWT令牌相关异常
        if isinstance(exc, (InvalidToken, TokenError)):
            if "messages" in response.data:
                jwt_error_msg = response.data["messages"][0]["message"]
                custom_response["message"] = jwt_error_msg
            else:
                custom_response["message"] = response.data.get("detail", "Invalid token")
            custom_response["data"] = {"token": custom_response["message"]}
        
        # 处理DRF常规验证错误(如Serializer、字段校验错误)
        elif isinstance(response.data, dict):
            errors = {}
            for field, details in response.data.items():
                # 处理列表型错误(如Serializer字段的错误列表)
                if isinstance(details, list):
                    errors[field] = details[0] if details else "Invalid input"
                # 处理嵌套字典型错误(如嵌套Serializer的错误)
                elif isinstance(details, dict):
                    errors[field] = " | ".join(f"{k}: {v[0]}" for k, v in details.items())
                # 处理单个字符串/其他类型错误
                else:
                    errors[field] = str(details)
            
            custom_response["message"] = " | ".join(errors.values())
            custom_response["data"] = errors
        
        # 兜底处理未知结构的错误
        else:
            custom_response["message"] = str(response.data)
            custom_response["data"] = {"error": str(response.data)}
        
        # 替换响应数据为统一格式
        response.data = custom_response
    
    return response

步骤2:在settings.py中配置自定义处理器

确保DRF启用你的异常处理函数:

REST_FRAMEWORK = {
    # 其他DRF配置...
    'EXCEPTION_HANDLER': '你的应用名.views.custom_exception_handler',
}

关键改进说明

  • JWT异常专属处理:识别InvalidToken、TokenError类型,提取JWT响应中友好的message字段,避免暴露code等内部标识。
  • 错误格式优化:对嵌套字典型错误做了更清晰的拼接,让data字段的错误信息更易读。
  • 兼容性兜底:对未知结构的错误做兼容处理,保证所有异常都输出统一格式。

测试效果示例

  • JWT令牌错误响应:
{
    "status": false,
    "responseCode": 0,
    "message": "Token is invalid or expired",
    "data": {
        "token": "Token is invalid or expired"
    }
}
  • 常规Serializer验证错误响应:
{
    "status": false,
    "responseCode": 0,
    "message": "username: 该用户名已存在 | email: 邮箱格式不正确",
    "data": {
        "username": "该用户名已存在",
        "email": "邮箱格式不正确"
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:14:51