Как отключить возврат страницы ошибок HTML с помощью рамки django rest?
Если у меня есть ошибка за пределами libs DRF, django отправляет HTML-код ошибки вместо правильного использования ответа ошибки DRF.
Например:
@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def downloadData(request):
print request.POST['tables']
Возвращает исключение MultiValueDictKeyError: "'tables'"
. И верните полный HTML. Как получить только ошибку JSON?
P.D:
Это окончательный код:
@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)
Ответы
Ответ 1
Одним из способов возврата 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 в промежуточное программное обеспечение исключения.
Вы можете найти пример в этом сообщении в блоге.
В вашем случае вам нужно вернуть ответ 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)
Ответ 2
Вы можете заменить обработчики ошибок по умолчанию, указав настраиваемый обработчик в URLConf как описано здесь.
Что-то вроде этого:
# 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
Я надеюсь, что это поможет.
Ответ 3
Как вы можете видеть в документации.
Все, что вам нужно сделать, это настроить параметры.
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
Моя реализация подобна этому, потому что, если возникает ожидаемое исключение рамки ожидания, например, 'exceptions.NotFound', exception.message
будет пустой. Вот почему я впервые позвонил в exception_handler
рамки отдыха. Если это ожидаемое исключение, я получу его сообщение.