Django Rest Framework - 处理API参数验证错误的最佳方法?

时间:2015-01-29 19:44:19

标签: python django django-rest-framework

在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}]}

那么,请您分享处理错误并返回错误的方法吗?

非常感谢,谢谢!

1 个答案:

答案 0 :(得分:2)

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的任何错误。< / p>

因此,在您的示例中,您可以通过执行

来引发类似的异常
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状态代码进行成功响应。