如何使用django rest框架禁用HTML错误页面的返回?

时间:2014-01-13 20:38:50

标签: django rest exception django-rest-framework

如果我在DRF的lib之外有错误,django会发回错误的HTML而不是DRF使用的正确错误响应。

例如:

@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def downloadData(request):
    print request.POST['tables']

返回例外MultiValueDictKeyError: "'tables'"。并获取完整的HTML。如何只获得错误JSON?

Pd积:

这是最终代码:

@api_view(['GET', 'POST'])
def process_exception(request, exception):
    # response = json.dumps({'status': status.HTTP_500_INTERNAL_SERVER_ERROR,
    #                        'message': str(exception)})
    # return HttpResponse(response,
    #                     content_type='application/json; charset=utf-8')
    return Response({
        'error': True,
        'content': unicode(exception)},
        status=status.HTTP_500_INTERNAL_SERVER_ERROR
    )


class ExceptionMiddleware(object):
    def process_exception(self, request, exception):
        # response = json.dumps({'status': status.HTTP_500_INTERNAL_SERVER_ERROR,
        #                        'message': str(exception)})
        # return HttpResponse(response,
        #                     content_type='application/json; charset=utf-8')
        print exception
        return process_exception(request, exception)

3 个答案:

答案 0 :(得分:9)

返回json的一种方法是捕获异常并返回正确的响应(假设您使用JSONParser作为默认解析器):

from rest_framework.response import Response
from rest_framework import status


@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def downloadData(request):
    try:
        print request.POST['tables']
    except:
        return Response({'error': True, 'content': 'Exception!'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return Response({'error': False})

<强>更新

对于全球明智的用例,正确的想法是将json响应放在exception middleware中。

您可以在this blog post中找到示例。

在您的情况下,您需要返回DRF响应,因此如果引发任何异常,它将最终出现在process_exception

from rest_framework.response import Response


class ExceptionMiddleware(object):

    def process_exception(self, request, exception):
        return Response({'error': True, 'content': exception}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

答案 1 :(得分:6)

您可以通过在URLConf as documented here

中指定自定义处理程序来替换默认错误处理程序

这样的事情:

# In urls.py
handler500 = 'my_app.views.api_500'

和:

# In my_app.views
def api_500(request):
    response = HttpResponse('{"detail":"An Error Occurred"}', content_type="application/json", status=500)
    return response

我希望有所帮助。

答案 2 :(得分:3)

正如您在documentation中所看到的那样。

您需要做的就是配置设置。

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
       'rest_framework.parsers.JSONParser',
    ),
    'EXCEPTION_HANDLER': 'core.views.api_500_handler',
}

指向将收到(exception, context)

的视图

像这样:

from rest_framework.views import exception_handler
...
def api_500_handler(exception, context):
    response = exception_handler(exception, context)
    try:
        detail = response.data['detail']
    except AttributeError:
        detail = exception.message
    response = HttpResponse(
        json.dumps({'detail': detail}),
        content_type="application/json", status=500
    )
    return response

我的实现是这样的,因为如果引发预期的休息框架异常,例如&#39; exceptions.NotFound&#39;,exception.message将为空。这就是为什么我第一次打电话给exception_handler休息框架。如果是预期的异常,我会得到它的消息。