Ответ
В Django HTTP-ответы формируются с помощью экземпляров класса HttpResponse и его подклассов. Каждый view-обработчик должен возвращать такой объект.
Основные классы для ответов:
-
HttpResponseБазовый класс для отправки текстового контента. Используется для возврата HTML, текста, XML и т.д.from django.http import HttpResponse def simple_view(request): return HttpResponse("Это простой текстовый ответ.", content_type="text/plain") -
JsonResponseСпециализированный подкласс для API. Автоматически сериализует Python-словари в JSON и устанавливает заголовокContent-Type: application/json.from django.http import JsonResponse def api_view(request): data = {'status': 'ok', 'data': [1, 2, 3]} return JsonResponse(data) -
HttpResponseRedirectИспользуется для перенаправления пользователя на другой URL. Обычно создается с помощью шорткатаredirect().from django.shortcuts import redirect def redirect_view(request): # Возвращает ответ с кодом 302 Found return redirect('/new-location/') -
TemplateResponseОтвет, рендеринг которого отложен. Это позволяет middleware-компонентам изменять контекст шаблона уже после того, как view его вернул, но до отправки клиенту.from django.template.response import TemplateResponse def template_view(request): context = {'user': request.user} return TemplateResponse(request, 'profile.html', context)
Кастомизация ответа
Любой объект ответа можно кастомизировать, изменяя его атрибуты, например, код состояния или заголовки:
response = HttpResponse("Страница не найдена", status=404)
response.headers['X-Custom-Header'] = 'MyValue' Ответ 18+ 🔞
Давай разберём эту тему про ответы в Джанго, а то я вижу, у некоторых в голове каша, как в общественном сортире после праздника.
Смотри, вся суть в том, что любой твой вью-обработчик в Джанго должен в итоге вернуть какой-то объект ответа. Это как в магазине: ты не можешь просто взять и мысленно пожелать покупателю хорошего дня — надо рот открыть и членораздельно буркнуть. Так и здесь. Ты должен вернуть конкретную штуку.
Основные инструменты в твоём арсенале:
-
HttpResponse— твой базовый кирпич. Это как сказать «да похуй» и выдать голый текст. HTML, XML, просто строку — что угодно.from django.http import HttpResponse def simple_view(request): return HttpResponse("Это простой текстовый ответ.", content_type="text/plain")Главное — не забыть указать
content_type, а то браузер начнёт гадать, что это за хуйню ты ему подсунул. -
JsonResponse— для API, чтобы не выёбываться. Хочешь отдать JSON? Не надо вручную делатьjson.dumps()и ставить заголовки, ёпта. Бери готовое.from django.http import JsonResponse def api_view(request): data = {'status': 'ok', 'data': [1, 2, 3]} return JsonResponse(data)Он сам всё сериализует и заголовок
application/jsonприлепит. Красота. -
HttpResponseRedirect— чтобы послать пользователя нахуй. Вернее, на другой URL. Чаще всего используется через шорткатredirect(), чтобы не париться.from django.shortcuts import redirect def redirect_view(request): # Пользователь пришёл сюда, а ты ему — а ну иди отсюда, на '/new-location/' return redirect('/new-location/')Код ответа будет 302 — «Найдено, но не здесь, иди туда».
-
TemplateResponse— хитрая жопа с отложенным рендерингом. Это не просто рендер шаблона, а такой умный ответ, который не рендерится сразу. Зачем? Чтобы разные промежуточные слои (middleware) могли ещё долбануть по контексту или шаблону, после того как вьюшка отработала, но до того как ответ улетел к пользователю.from django.template.response import TemplateResponse def template_view(request): context = {'user': request.user} return TemplateResponse(request, 'profile.html', context)Мощная штука, но если не понимаешь зачем — не трогай, а то накосячишь.
А если хочешь настроить ответ под себя?
Да без проблем! Любой объект ответа — это же просто питонячий объект. Хочешь поменять код статуса? Пожалуйста. Хочешь прилепить свой заголовок? Да хули бы и нет.
response = HttpResponse("Страница не найдена", status=404)
response.headers['X-Custom-Header'] = 'MyValue'
Вот и всё. Главное — понимать, что ты возвращаешь, а не просто тыкать в первый попавшийся класс, как мартышка в клавиатуру.