Чем статус HttpResponse в Django отличается от status_code?

Я пытаюсь настроить некоторые пользовательские представления ошибок в приложении Django, но я столкнулся с тем, что не совсем понимаю, как работает HttpResponse.

Когда я возвращаю HttpResponse(status=500), Django не отображает шаблон 500.html. Однако, когда я возвращаю, используя status_code HttpResponse(status_code=500), он работает.

Вот шаги к решению моей проблемы:

  1. Установите handler500 = views.handler500
  2. Постройте handler500 вид:
def handler500(request):
    return render(request, '500.html', status=500)
  1. Попробуйте воспроизвести ошибку 500:
def cart(request):
    return HttpResponse(status=500)

Я пытаюсь предотвратить необходимость рефакторинга сотен представлений в существующей кодовой базе с status=500 на status_code=500. Я беспокоюсь о том, что могу что-то сломать. Что еще более важно, я пытаюсь понять разницу между этими двумя вариантами.

Когда я читаю исходный код Django для response.py, кажется, что они преобразуют status в status_code в любом случае внутри class HttpResponseBase. Любой совет будет высоко оценен.

Аргумент, который хочет получить HttpResponse, - это status=<int>. Как вы заметили, он превращается в свойство httpresponse.status_code. Однако все, что это делает, заставляет заголовки ответов включать код ошибки 500.

Обработчик handler500 вызывается, когда в представлении возникает ошибка. На самом деле он не вызывается кодом ошибки 500 в заголовках ответов.

Я подозреваю, что использование неожиданного аргумента ключевого слова status_code = <int> в представлении создает ошибку, необходимую для вызова обработчика500. Тот факт, что это именно та ошибка, которая вам нужна, запутывает ситуацию. Вы можете проверить это, сделав status_code = 404 и посмотрев, получите ли вы ответ 500.

Возврат HttpResponse(status=500)

Возврат HttpResponse(status=500) просто отправляет ответ с кодом состояния HTTP 500, но не вызывает вызов обработчика ошибок. Пожалуйста, обратитесь к смежному вопросу: Как работает HttpResponse(status=<code>) в django?

Если вы хотите воспроизвести ошибку 500, самый простой способ - просто поднять необработанное исключение в вашем представлении, например:

def cart(request):
    raise Exception()

Почему возврат HttpResponse(status_code=500) вызывает вызов обработчика ошибок

Метод HttpResponse __init__() не принимает аргумент ключевого слова status_code. Попытка создать экземпляр HttpResponse вызовом HttpResponse(status_code=500) вызовет исключение:

TypeError: init() получил неожиданный аргумент ключевого слова status_code

и если он не будет обработан, будет вызван обработчик ошибок (пользовательский, если он установлен, или по умолчанию в противном случае) для обработки исключения и вывода вашей страницы 500.html.

Обратитесь к документации по django: https://docs.djangoproject.com/en/4.1/ref/views/#the-500-server-error-view

Django выполняет специальное поведение в случае ошибок в коде представления. Если представление приводит к исключению, Django по умолчанию вызывает представление django.views.defaults.server_error, которое либо выдает сообщение "Server Error", либо загружает и отображает шаблон 500.html, если вы создали его в корневом каталоге шаблонов.

.
Вернуться на верх