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

