【问题标题】:Django REST ExceptionsDjango REST 异常
【发布时间】:2015-08-12 05:34:17
【问题描述】:

我目前有一些基于 Django REST 框架的视图代码。 我一直在使用客户异常类,但理想情况下我想使用内置的 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)

【问题讨论】:

    标签: django rest django-rest-framework


    【解决方案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 异常被转换为响应,更多信息请参见我的回答
    猜你喜欢
    • 2015-10-24
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2018-07-23
    相关资源
    最近更新 更多