Django REST 异常
Posted
技术标签:
【中文标题】Django REST 异常【英文标题】:Django REST Exceptions 【发布时间】:2015-08-12 05:34:17 【问题描述】:我目前有一些基于 Django REST 框架的视图代码。 我一直在使用客户异常类,但理想情况下我想使用内置的 。
从下面的代码中,我觉得这可能不是最大限度地利用 REST 框架异常的最佳或最干净的方式。
有没有人有任何很好的例子来捕捉问题并使用 REST 内置异常干净地返回它们?
class JSONResponse(HttpResponse):
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
def queryInput(request):
try:
auth_token = session_id = getAuthHeader(request)
if not auth_token:
return JSONResponse('detail' : "fail", "error" : "No X-Auth-Token Found", "data" : None, status=500)
if request.method:
data = JSONParser().parse(request)
serializer = queryInputSerializer(data=data)
if request.method == 'POST':
if serializer.is_valid():
input= serializer.data["input"]
fetchData = MainRunner(input=input,auth_token=auth_token)
main_data = fetchData.main()
if main_data:
return JSONResponse('detail' : "success", "error" : None, "data" : main_data, status=201)
return JSONResponse('detail' : "Unknown Error","error" : True, "data" : None, status=500)
except Exception as e:
return JSONResponse('error' : str(e),status=500)
【问题讨论】:
【参考方案1】:Django REST 框架提供了几个built in exceptions,它们大多是DRF 的APIException
的子类。
您可以像在 Python 中一样在视图中引发异常:
from rest_framework.exceptions import APIException
def my_view(request):
raise APIException("There was a problem!")
您还可以通过从APIException
继承并设置status_code
和default_detail
来创建自己的自定义异常。一些内置的有:ParseError
、AuthenticationFailed
、NotAuthenticated
、PermissionDenied
、NotFound
、NotAcceptable
、ValidationError
等。
这些将被 REST 框架的异常处理程序转换为 Response
。每个异常都与添加到Response
的状态代码相关联。默认情况下,异常处理程序设置为内置处理程序:
REST_FRAMEWORK =
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
但是,如果您想通过在 settings.py
文件中更改它来自己转换异常,则可以将其设置为您自己的自定义异常处理程序:
REST_FRAMEWORK =
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
然后在该位置创建自定义处理程序:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now add the HTTP status code to the response.
if response is not None:
response.data['status_code'] = response.status_code
return response
【讨论】:
导入错误:无法为 API 设置“EXCEPTION_HANDLER”导入“my_project.my_app.utils.custom_exception_handler”。 AttributeError:模块 my_project.my_app.utils' 没有属性 'custom_exception_handler'。【参考方案2】:您可以使用build in DRF exception,只需导入并提高
from rest_framework.exceptions import
...
raise ParseError('I already have a status code!')
【讨论】:
这只是引发了异常。它不应该也发送响应吗? 试试raise APIException("这个错误会出现") or PermissionDenied, ValidationError Not sure about ParserError @felix001 异常被转换为响应,更多信息请参见我的回答以上是关于Django REST 异常的主要内容,如果未能解决你的问题,请参考以下文章
Django-rest-framework 中的全局异常处理
如何在 Django rest 框架中捕获 Model.DoesNotExist 异常?
Django Rest Framework JWT 中的 ValidationError 不使用自定义异常处理程序