Django Rest框架 - 处理API参数验证错误的最佳方式? [英] Django Rest Framework - Best way to deal with API parameter validation errors?

查看:1620
本文介绍了Django Rest框架 - 处理API参数验证错误的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



目前,正如我所说:

 除了Section.DoesNotExist:
返回响应(headers = {'INTERNAL_MSG':'SECTION_NOT_FOUND',
'INTERNAL_CODE':' 400'},
status = status.HTTP_200_OK)

但是,在我看来是不是一个很好的方法,因为我在HTTP协议中注入内部错误消息,与HTTP拓扑无关。



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

  {errors:[{message :对不起,该页面不存在,代码:34}]} 

你可以分享你处理错误的方法,并返回他们吗?



非常感谢,谢谢!

解决方案

Django REST框架内部处理错误,一般来说,成为可以由客户解析的合理回应。这是由内部异常处理完成的扩展为特殊情况。



通常当您遇到指定不存在的对象的情况下,您提出一个 404未找到错误。 Django实际上有一个帮手,称为 get_object_or_404 ,因为它往往是一个很常见的逻辑,特别是在API。 Django REST框架将转换此引发的 Http404 错误,并将其转换为具有404 HTTP错误代码的以下响应。

  {
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
从rest_framework导入状态

exc_data = {
errors:[],
}

如果isinstance(exc,Http404):
exc_data [errors]。append({
message:对不起,该页面不存在,
code:404,
})
else if isinstance(exc.detail,list):
在exc.detail中的消息:
exc_data [errors]。append({
message:message,
code:exc.status_code,
}
else:
exc_data [errors]。append({
message:exc.detail,
code:exc.status_code,
})

返回响应(exc_data,status = status.HTTP_200_OK)

请注意,这将给出所有错误回复状态码为200,并将实际的HTTP状态代码嵌入正文。这对于某些应用程序非常有用,但通常建议仅使用200状态代码进行成功响应。


What would be an efficient way to construct error messages during HTTP request parameter validation and serialize them?

Currently, as I have it:

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

But, it seems to me this is a not a good way to do it, since I am injecting internal error messages into the HTTP protocol that have nothing to do with HTTP topology.

Preferably, I would like to do something like Twitter, Facebook, and others are doing in their APIs:

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

So, could you please share your approach to dealing with errors and returning them?

Very much appreciated, thanks!

解决方案

Django REST framework handles errors internally and in general does a pretty good job of converting them into reasonable responses that can be parsed by clients. This is done by the internal exception handling, which is open to being extended for special cases.

Usually when you run into a case where an object was specified that does not exist, you raise a 404 Not Found error. Django actually has a helper for this, called get_object_or_404, as it tends to be a very common bit of logic, especially in APIs. Django REST framework will convert this Http404 error that is raised and convert it in to the following response that has a 404 HTTP error code.

{
  "detail": "Not found"
}

Now, this format (and object with a detail key) is not restricted to only Http404 errors, it works for any error that subclasses APIError provided by Django REST framework.

So in your example, you could raise a similar exception by doing

ex = APIError("Section not found")
ex.status_code = 404

raise ex

Or by using get_object_or_404 and letting Django REST framework handle it

from django.shortcuts import get_object_or_404
section = get_object_or_404(Section.objects, pk=1234)

Of course, you can still override the exception handler to format these errors how you want.

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)

Note that this will give all error responses a status code of 200, and embed the actual HTTP status code within the body. This is useful for some applications, but it is usually recommended to only use the 200 status code for success responses.

这篇关于Django Rest框架 - 处理API参数验证错误的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆