Каков жизненный цикл HTTP-ответа в Django после его формирования во view?

Ответ

После того как view-функция в Django обработала запрос, она формирует и возвращает объект HttpResponse (или его подкласс, например, JsonResponse, HttpResponseRedirect). Этот объект является "чертежом" будущего HTTP-ответа.

Дальнейший жизненный цикл ответа выглядит так:

  1. Проход через Middleware (в обратном порядке): Сформированный HttpResponse передается слоям Middleware. Важно, что он проходит через них в порядке, обратном тому, как через них проходил входящий запрос.

    • Путь запроса: Middleware 1 -> Middleware 2 -> View
    • Путь ответа: View -> Middleware 2 -> Middleware 1

    Каждый middleware может проинспектировать или модифицировать объект ответа. Например, добавить заголовки (Content-Security-Policy), сжать контент (GZipMiddleware) или установить cookie.

  2. Отправка веб-серверу: После прохождения всех слоев middleware, итоговый HttpResponse передается WSGI-серверу (например, Gunicorn или uWSGI).

  3. Отправка клиенту: WSGI-сервер преобразует объект HttpResponse в настоящий HTTP-ответ и отправляет его по сети клиенту (браузеру).

Пример view и middleware:

# myapp/views.py
from django.http import JsonResponse

def api_user_profile(request):
    # View формирует базовый ответ
    data = {"username": "testuser", "is_active": True}
    return JsonResponse(data)

# myproject/middleware.py
class CustomHeaderMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Код до view (обработка запроса)
        response = self.get_response(request)
        # Код после view (обработка ответа)
        # Middleware добавляет кастомный заголовок ко всем ответам
        response['X-Custom-Header'] = 'my-value'
        return response

В этом примере JsonResponse сначала создается во view, а затем CustomHeaderMiddleware добавляет в него заголовок X-Custom-Header перед отправкой клиенту.