#django-rest-framework
#django-rest-framework
Вопрос:
У меня есть пользовательская функция server_error для возврата ответа json на ошибку 500 с использованием DRF:
def api_server_error(request, template_name=None):
return HttpResponseServerError(json.dumps({'detail': 'Internal server error'}),
content_type="application/json", status=500)
Но что я действительно хочу сделать, так это отобразить ответ в запрошенном формате, например, xml, json и т.д. Как мне это сделать?
Ответ №1:
Возвращая ответ drf:
из rest_framework.response импортируйте ответ из статуса импорта rest_framework верните ответ ({'detail': "Внутренняя ошибка сервера"}, статус = status.HTTP_500_INTERNAL_SERVER_ERROR)
Комментарии:
1. Спасибо, что помогли мне начать в правильном направлении. Смотрите полное решение ниже.
Ответ №2:
Хорошо, благодаря @djangozone, который направил меня в правильном направлении, я нашел решение. Мой вопрос начался с того, что я предположил, что, поскольку server_error вызывается вне DRF, это ограничит мою способность использовать функции DRF для доставки правильно отформатированного ответа. Нужно было проделать еще кое-какую работу, чтобы заставить DRF отображать его должным образом. Вот оно:
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework import status
import re
def get_format_suffix(request):
suffix_pattern = r'.([a-z0-9] )$'
match = re.search(suffix_pattern, request.path)
format = match and match.group(1)
return format
def api_server_error(request, template_name=None):
drf_request = Request(request)
format_suffix = get_format_suffix(drf_request)
accepted_renderer = drf_request.negotiator.select_renderer(
drf_request, [renderer() for renderer in api_settings.DEFAULT_RENDERER_CLASSES], format_suffix=format_suffix
)
response = Response({'detail' : "Internal server error"}, status = status.HTTP_500_INTERNAL_SERVER_ERROR)
response.accepted_renderer = accepted_renderer[0]
response.accepted_media_type = response.accepted_renderer.media_type
response.renderer_context = {'request': drf_request}
response.render()
return response
Комментарии:
1. Лол, я думал, что это будет работать таким образом по умолчанию. Если вы посмотрите в исходном коде rest_framework, в файле mixings.py метод all всегда возвращает ответ, не выполняя всего того, что вы делаете (и это работает, когда вы запрашиваете определенный метод рендеринга с помощью .xml, .json и т.д. Ofc, вам нужно указать классы средства визуализации в ваших настройках или представлении). Не знаю, есть ли лучший способ добиться этого или где rest_framework делает это.
2. Проблема в том, что дополнительный код, который я написал, — это то, что представление на самом деле делает за кулисами, а server_error работает вне представления. Поскольку здесь мы не работаем с представлением для выполнения работы, мне пришлось скопировать соответствующие части.
3. ах, хорошо. Я также изучу это, когда у меня будет время. Рад, что теперь это работает ^^.