Skip to main content
 首页 » 编程设计

python之Django Rest Framework之处理 API 参数验证错误的最佳方式

2024年10月25日42langtianya

在 HTTP 请求参数验证期间构造错误消息并将其序列化的有效方法是什么?

目前,据我所知:

except Section.DoesNotExist: 
            return Response(headers = {'INTERNAL_MSG': 'SECTION_NOT_FOUND', 
                                       'INTERNAL_CODE': '400'}, 
                            status = status.HTTP_200_OK) 

但是,在我看来这不是一个好的方法,因为我将内部错误消息注入(inject)到 HTTP 协议(protocol)中,而这与 HTTP 拓扑无关。

最好,我想做一些像 Twitter、Facebook 和其他人在他们的 API 中做的事情:

{"errors":[{"message":"Sorry, that page does not exist","code":34}]} 

那么,您能否分享一下您处理错误并返回错误的方法?

非常感谢,谢谢!

请您参考如下方法:

Django REST 框架在内部处理错误,通常可以很好地将错误转换为客户端可以解析的合理响应。这是由 internal exception handling 完成的,可以针对特殊情况进行扩展。

通常当您遇到指定的对象不存在的情况时,您会引发 404 Not Found错误。 Django 实际上有一个 helper ,called get_object_or_404 ,因为它往往是一种非常常见的逻辑,尤其是在 API 中。 Django REST 框架将转换此 Http404引发的错误并将其转换为以下具有 404 HTTP 错误代码的响应。

{ 
  "detail": "Not found" 
} 

现在,这种格式(和带有 detail 键的对象)不仅仅限于 Http404错误,它适用于子类 APIError 的任何错误由 Django REST 框架提供。

因此在您的示例中,您可以通过执行以下操作来引发类似的异常

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 状态代码来进行成功响应。