2014-01-13 43 views
11

如果我在DRF的库之外有错误,django会发回错误的HTML而不是DRF正确的错误响应。如何禁用django rest框架返回HTML错误页面?

例如:

@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) 

回答

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}) 

UPDATE

对于全局明智的用例,正确的想法是将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) 
+0

是的,但那requiere修补每个视图。我想知道是否存在可以在全球范围内使用的东西 – mamcx

+0

@mamcx我已经更新了我的答案。请看一下。 – mariodev

+0

不错,@mariodev。 DRF应该包含这个,它是JSON API返回HTML的糟糕形式。也许你应该提交它? ;-) – s29

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 

我希望有帮助。

1

正如您在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 

我的实现是这样的,因为如果一个预期的REST框架异常引发,类似“exceptions.NotFound” ,exception.message将为空。这就是为什么林首先打电话给exception_handler的休息框架。如果是预期的例外,我会得到它的信息。

相关问题