Django Rest Framework - 处理 API 参数验证错误的最佳方式?
Django Rest Framework - Best way to deal with API parameter validation errors?
在 HTTP 请求参数验证期间构造错误消息并将其序列化的有效方法是什么?
目前,据我所知:
except Section.DoesNotExist:
return Response(headers = {'INTERNAL_MSG': 'SECTION_NOT_FOUND',
'INTERNAL_CODE': '400'},
status = status.HTTP_200_OK)
但是,在我看来,这不是一个好的方法,因为我将内部错误消息注入到与 HTTP 拓扑无关的 HTTP 协议中。
最好,我想做一些像 Twitter、Facebook 和其他人在他们的 API 中做的事情:
{"errors":[{"message":"Sorry, that page does not exist","code":34}]}
那么,能否请您分享一下您处理错误并返回错误的方法?
非常感谢,谢谢!
Django REST 框架在内部处理错误,通常可以很好地将错误转换为客户端可以解析的合理响应。这是由 internal exception handling 完成的,它可以针对特殊情况进行扩展。
通常 当您 运行 遇到指定对象不存在的情况时,您会引发 404 Not Found
错误。 Django 实际上有一个帮助程序,called get_object_or_404
,因为它往往是一个非常常见的逻辑位,尤其是在 API 中。 Django REST 框架将转换此 Http404
引发的错误并将其转换为以下具有 404 HTTP 错误代码的响应。
{
"detail": "Not found"
}
现在,这种格式(以及带有 detail
键的对象)不仅限于 Http404
错误,它适用于 Django REST 框架提供的子类 APIError
的任何错误.
因此在您的示例中,您可以通过执行以下操作来引发类似的异常
ex = APIError("Section not found")
ex.status_code = 404
raise ex
或者使用 get_object_or_404
并让 Django REST 框架处理它
from django.shortcuts import get_object_or_404
section = get_object_or_404(Section.objects, pk=1234)
当然,您仍然可以覆盖异常处理程序以按照您的需要格式化这些错误。
def exception_handler(exc):
from django.http import Http404
from rest_framework import status
exc_data = {
"errors": [],
}
if isinstance(exc, Http404):
exc_data["errors"].append({
"message": "Sorry that page does not exist",
"code": 404,
})
else if isinstance(exc.detail, list):
for message in exc.detail:
exc_data["errors"].append({
"message": message,
"code": exc.status_code,
}
else:
exc_data["errors"].append({
"message": exc.detail,
"code": exc.status_code,
})
return Response(exc_data, status=status.HTTP_200_OK)
请注意,这将为所有错误响应提供状态代码 200,并将实际的 HTTP 状态代码嵌入正文中。这对某些应用程序很有用,但通常建议只使用 200 状态码来响应成功。
在 HTTP 请求参数验证期间构造错误消息并将其序列化的有效方法是什么?
目前,据我所知:
except Section.DoesNotExist:
return Response(headers = {'INTERNAL_MSG': 'SECTION_NOT_FOUND',
'INTERNAL_CODE': '400'},
status = status.HTTP_200_OK)
但是,在我看来,这不是一个好的方法,因为我将内部错误消息注入到与 HTTP 拓扑无关的 HTTP 协议中。
最好,我想做一些像 Twitter、Facebook 和其他人在他们的 API 中做的事情:
{"errors":[{"message":"Sorry, that page does not exist","code":34}]}
那么,能否请您分享一下您处理错误并返回错误的方法?
非常感谢,谢谢!
Django REST 框架在内部处理错误,通常可以很好地将错误转换为客户端可以解析的合理响应。这是由 internal exception handling 完成的,它可以针对特殊情况进行扩展。
通常 当您 运行 遇到指定对象不存在的情况时,您会引发 404 Not Found
错误。 Django 实际上有一个帮助程序,called get_object_or_404
,因为它往往是一个非常常见的逻辑位,尤其是在 API 中。 Django REST 框架将转换此 Http404
引发的错误并将其转换为以下具有 404 HTTP 错误代码的响应。
{
"detail": "Not found"
}
现在,这种格式(以及带有 detail
键的对象)不仅限于 Http404
错误,它适用于 Django REST 框架提供的子类 APIError
的任何错误.
因此在您的示例中,您可以通过执行以下操作来引发类似的异常
ex = APIError("Section not found")
ex.status_code = 404
raise ex
或者使用 get_object_or_404
并让 Django REST 框架处理它
from django.shortcuts import get_object_or_404
section = get_object_or_404(Section.objects, pk=1234)
当然,您仍然可以覆盖异常处理程序以按照您的需要格式化这些错误。
def exception_handler(exc):
from django.http import Http404
from rest_framework import status
exc_data = {
"errors": [],
}
if isinstance(exc, Http404):
exc_data["errors"].append({
"message": "Sorry that page does not exist",
"code": 404,
})
else if isinstance(exc.detail, list):
for message in exc.detail:
exc_data["errors"].append({
"message": message,
"code": exc.status_code,
}
else:
exc_data["errors"].append({
"message": exc.detail,
"code": exc.status_code,
})
return Response(exc_data, status=status.HTTP_200_OK)
请注意,这将为所有错误响应提供状态代码 200,并将实际的 HTTP 状态代码嵌入正文中。这对某些应用程序很有用,但通常建议只使用 200 状态码来响应成功。