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_codedefault_detail 来创建自己的自定义异常。一些内置的有:ParseErrorAuthenticationFailedNotAuthenticatedPermissionDeniedNotFoundNotAcceptableValidationError等。

这些将被 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 异常处理

Django-rest-framework 中的全局异常处理

如何在 Django rest 框架中捕获 Model.DoesNotExist 异常?

Django Rest Framework JWT 中的 ValidationError 不使用自定义异常处理程序

django-rest-framework框架总结之认证权限限流过滤分页及异常处理

django-rest-framework框架总结之认证权限限流过滤分页及异常处理