Объекты запроса и ответа

Краткая информация

Django использует объекты запроса и ответа для передачи состояния через систему.

Когда страница запрашивается, Django создает объект HttpRequest, содержащий метаданные о запросе. Затем Django загружает соответствующее представление, передавая HttpRequest в качестве первого аргумента функции представления. Каждое представление отвечает за возврат объекта HttpResponse.

Этот документ объясняет API для объектов HttpRequest и HttpResponse, которые определены в модуле django.http.

Объекты HttpRequest

class HttpRequest[исходный код]

Атрибуты

Все атрибуты должны считаться доступными только для чтения, если не указано иное.

HttpRequest.scheme

Строка, представляющая схему запроса (обычно http или https).

HttpRequest.body

Необработанное тело HTTP-запроса в виде байтовой строки. Это полезно для обработки данных разными способами, чем обычные формы HTML: двоичные изображения, полезная нагрузка XML и т.д. Для обработки данных обычной формы используйте HttpRequest.POST.

Вы также можете читать из HttpRequest, используя файловый интерфейс HttpRequest.read() или HttpRequest.readline(). Доступ к атрибуту body после чтения запроса с помощью любого из этих методов потока ввода-вывода приведет к возникновению исключения RawPostDataException.

HttpRequest.path

Строка, представляющая полный путь к запрашиваемой странице, не включая схему, домен или строку запроса.

Например: "/music/bands/the_beatles/"

HttpRequest.path_info

В некоторых конфигурациях веб-серверов часть URL после имени хоста разделяется на часть префикса скрипта и часть информации о пути. Атрибут path_info всегда содержит информационную часть пути, независимо от того, какой веб-сервер используется. Использование этого атрибута вместо path может облегчить перемещение кода между тестовыми и развертывающими серверами.

Например, если WSGIScriptAlias для вашего приложения установлен на "/minfo", тогда path может быть "/minfo/music/band/the_beatles/" и path_info будет "/music/band/the_beatles/".

HttpRequest.method

Строка, представляющая метод HTTP, используемый в запросе. Это гарантированно будет в верхнем регистре. Например:

if request.method == "GET":
    do_something()
elif request.method == "POST":
    do_something_else()
HttpRequest.encoding

Строка, представляющая текущую кодировку, используемую для декодирования данных отправки формы (или None, что означает, что используется параметр DEFAULT_CHARSET). Вы можете записать в этот атрибут, чтобы изменить кодировку, используемую при доступе к данным формы. При любом последующем доступе к атрибуту (например, чтение из GET или POST) будет использоваться новое значение encoding. Полезно, если вы знаете, что данные формы не находятся в кодировке DEFAULT_CHARSET.

HttpRequest.content_type

Строка, представляющая MIME-тип запроса, извлеченная из заголовка CONTENT_TYPE.

HttpRequest.content_params

Словарь параметров ключ/значение, включенных в заголовок CONTENT_TYPE.

HttpRequest.GET

Словарный объект, содержащий все заданные параметры HTTP GET. Смотрите документацию QueryDict ниже.

HttpRequest.POST

Подобный словарю объект, содержащий все заданные параметры HTTP POST, при условии, что запрос содержит данные формы. Смотрите документацию QueryDict ниже. Если вам нужно получить доступ к необработанным данным или данным, не относящимся к форме, размещенным в запросе, используйте вместо этого атрибут HttpRequest.body.

Возможно, что запрос может поступить через POST с пустым словарем POST - если, скажем, форма запрашивается через метод POST HTTP, но не включает данные формы. Таким образом, не следует использовать if request.POST для проверки использования метода POST; вместо этого используйте if request.method == "POST" (смотрите attr:HttpRequest.method).

POST не включает информацию о загрузке файла. Смотрите attr:FILES.

HttpRequest.COOKIES

Словарь, содержащий все файлы cookie. Ключи и значения представляют собой строки.

HttpRequest.FILES

Словарный объект, содержащий все загруженные файлы. Каждый ключ в FILES - это name из <input type="file" name="">. Каждое значение в FILES - это UploadedFile.

Смотрите Управление файлами для получения дополнительной информации.

FILES будет содержать данные только в том случае, если метод запроса был POST, а <form>, отправленная в запрос, имела enctype="multipart/form-data". В противном случае FILES будет пустым объектом, похожим на словарь.

HttpRequest.META

Словарь, содержащий все доступные заголовки HTTP. Доступные заголовки зависят от клиента и сервера, но вот несколько примеров:

  • CONTENT_LENGTH - длина тела запроса (в виде строки).
  • CONTENT_TYPE – MIME-тип тела запроса.
  • HTTP_ACCEPT – допустимые типы содержимого для ответа.
  • HTTP_ACCEPT_ENCODING – допустимые кодировки для ответа.
  • HTTP_ACCEPT_LANGUAGE - допустимые языки для ответа.
  • HTTP_HOST – заголовок HTTP-хоста, отправляемый клиентом.
  • HTTP_REFERER – ссылающаяся страница, если есть.
  • HTTP_USER_AGENT - строка агента клиента.
  • QUERY_STRING - строка запроса в виде единственной (неанализируемой) строки.
  • REMOTE_ADDR - IP-адрес клиента.
  • REMOTE_HOST - имя хоста клиента.
  • REMOTE_USER – Пользователь, аутентифицированный веб-сервером, если таковой имеется.
  • REQUEST_METHOD - строка, такая как GET или POST.
  • SERVER_NAME - имя хоста сервера.
  • SERVER_PORT – порт сервера (в виде строки).

За исключением CONTENT_LENGTH и CONTENT_TYPE, как указано выше, любые заголовки HTTP в запросе преобразуются в ключи META путем преобразования всех символов в верхний регистр, замены дефисов символами подчеркивания и добавления символа префикса HTTP_ к имени. Так, например, заголовок X-Bender будет сопоставлен с ключом META HTTP_X_BENDER.

Обратите внимание, что runserver удаляет все заголовки с символами подчеркивания в имени, поэтому вы не увидите их в META. Это предотвращает подмену заголовков, основанную на двусмысленности между подчеркиванием и тире, которые нормализуются к подчеркиванию в переменных окружения WSGI. Это соответствует поведению таких веб-серверов, как Nginx и Apache 2.4+.

HttpRequest.headers - это более простой способ получить доступ ко всем заголовкам с префиксом HTTP, плюс CONTENT_LENGTH и CONTENT_TYPE.

HttpRequest.headers

Нечувствительный к регистру объект типа dict, который обеспечивает доступ ко всем заголовкам с префиксом HTTP (плюс Content-Length и Content-Type) из запроса.

Имя каждого заголовка при отображении стилизуется под заголовок (например, User-Agent). Обращаться к заголовкам можно без учета регистра:

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> "User-Agent" in request.headers
True
>>> "user-agent" in request.headers
True

>>> request.headers["User-Agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers["user-agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get("User-Agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get("user-agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

Для использования, например, в шаблонах Django, заголовки также можно искать, используя подчеркивание вместо дефиса:

{{ request.headers.user_agent }}
HttpRequest.resolver_match

Экземпляр ResolverMatch, представляющий разрешенный URL. Этот атрибут устанавливается только после того, как произошло разрешение URL, что означает, что он доступен во всех представлениях, но не в промежуточном программном обеспечении middleware, которое выполняется до того, как происходит разрешение URL (хотя вы можете использовать его в process_view()).

Атрибуты, установленные кодом приложения

Django сам не устанавливает эти атрибуты, но использует их, если они установлены вашим приложением.

HttpRequest.current_app

Тег шаблона url будет использовать свое значение в качестве аргумента current_app для reverse().

HttpRequest.urlconf

Он будет использоваться как корневой URLconf для текущего запроса, переопределив параметр ROOT_URLCONF. Смотрите Как Django обрабатывает запрос для подробностей.

Для параметра urlconf можно задать значение None, чтобы отменить любые изменения, сделанные предыдущим промежуточным программным обеспечением, и вернуться к использованию ROOT_URLCONF.

HttpRequest.exception_reporter_filter

Будет использоваться вместо DEFAULT_EXCEPTION_REPORTER_FILTER для текущего запроса. Смотрите Пользовательские отчеты об ошибках для подробностей.

HttpRequest.exception_reporter_class

Будет использоваться вместо DEFAULT_EXCEPTION_REPORTER для текущего запроса. Смотрите Пользовательские отчеты об ошибках для подробностей.

Атрибуты, установленные промежуточным программным обеспечением middleware

Некоторые из middleware, включенного в приложения contrib Django, устанавливают атрибуты по запросу. Если вы не видите атрибут в запросе, убедитесь, что соответствующий класс промежуточного ПО указан в MIDDLEWARE.

HttpRequest.session

Из SessionMiddleware: читаемый и записываемый, подобный словарю объект, представляющий текущий сеанс.

HttpRequest.site

Из CurrentSiteMiddleware: экземпляр Site или RequestSite, возвращенный get_current_site(), представляющий текущий сайт.

HttpRequest.user

Из AuthenticationMiddleware: экземпляр AUTH_USER_MODEL, представляющий текущего вошедшего в систему пользователя. Если пользователь в настоящее время не вошел в систему, user будет установлен как экземпляр AnonymousUser. Вы можете отличить их друг от друга с помощью is_authenticated, например:

if request.user.is_authenticated:
    ...  # Do something for logged-in users.
else:
    ...  # Do something for anonymous users.

Метод auser() делает то же самое, но может использоваться из асинхронных контекстов.

Методы

HttpRequest.auser()
New in Django 5.0.

Из AuthenticationMiddleware: Coroutine. Возвращает экземпляр AUTH_USER_MODEL, представляющий текущего вошедшего в систему пользователя. Если пользователь в данный момент не вошел в систему, auser вернет экземпляр AnonymousUser. Это похоже на атрибут user, но работает в асинхронном контексте.

HttpRequest.get_host()[исходный код]

Возвращает исходный хост запроса, используя информацию из заголовков HTTP_X_FORWARDED_HOST (если USE_X_FORWARDED_HOST включен) и HTTP_HOST в указанном порядке. Если они не предоставляют значение, метод использует комбинацию SERVER_NAME и SERVER_PORT, как подробно описано в PEP 3333.

Пример: "127.0.0.1:8000"

Поднимает django.core.exceptions.DisallowedHost, если хост не находится в ALLOWED_HOSTS или доменное имя недопустимо согласно RFC 1034/1035.

Примечание

Метод get_host() не работает, когда хост находится за несколькими прокси. Одним из решений является использование промежуточного программного обеспечения middleware для перезаписи заголовков прокси, как в следующем примере:

class MultipleProxyMiddleware:
    FORWARDED_FOR_FIELDS = [
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED_HOST",
        "HTTP_X_FORWARDED_SERVER",
    ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """
        Rewrites the proxy headers so that only the most
        recent proxy is used.
        """
        for field in self.FORWARDED_FOR_FIELDS:
            if field in request.META:
                if "," in request.META[field]:
                    parts = request.META[field].split(",")
                    request.META[field] = parts[-1].strip()
        return self.get_response(request)

Это промежуточное ПО должно быть расположено перед любым другим промежуточным ПО, которое полагается на значение get_host() – например, CommonMiddleware или CsrfViewMiddleware.

HttpRequest.get_port()[исходный код]

Возвращает исходный порт запроса, используя информацию из переменных HTTP_X_FORWARDED_PORT (если USE_X_FORWARDED_PORT включен) и SERVER_PORT и META в указанном порядке.

HttpRequest.get_full_path()[исходный код]

Возвращает path плюс добавленную строку запроса, если применимо.

Пример: "/music/groups/the_beatles/?print=true"

HttpRequest.get_full_path_info()[исходный код]

Например get_full_path(), но использует path_info вместо path.

Пример: "/minfo/music/bands/the_beatles/?print=true"

HttpRequest.build_absolute_uri(location=None)[исходный код]

Возвращает абсолютную форму URI для location. Если местоположение не указано, для него будет установлено значение request.get_full_path().

Если местоположение уже является абсолютным URI, оно не будет изменено. В противном случае абсолютный URI создается с использованием переменных сервера, доступных в этом запросе. Например:

>>> request.build_absolute_uri()
'https://example.com/music/bands/the_beatles/?print=true'
>>> request.build_absolute_uri("/bands/")
'https://example.com/bands/'
>>> request.build_absolute_uri("https://example2.com/bands/")
'https://example2.com/bands/'

Примечание

Смешивание HTTP и HTTPS на одном сайте не рекомендуется, поэтому build_absolute_uri() всегда будет генерировать абсолютный URI с той же схемой, которую имеет текущий запрос. Если вам нужно перенаправить пользователей на HTTPS, лучше всего позволить вашему веб-серверу перенаправить весь HTTP-трафик на HTTPS.

Возвращает значение cookie для подписанного файла cookie или вызывает исключение django.core.signing.BadSignature, если подпись больше не действительна. Если вы укажете аргумент default, исключение будет подавлено, и вместо него будет возвращено значение по умолчанию.

Необязательный аргумент salt может использоваться для обеспечения дополнительной защиты от атак грубой силы на ваш секретный ключ. Если указан аргумент max_age, он будет сравниваться с подписанной меткой времени, прикрепленной к значению куки, чтобы убедиться, что куки не старше, чем max_age секунд.

Например:

>>> request.get_signed_cookie("name")
'Tony'
>>> request.get_signed_cookie("name", salt="name-salt")
'Tony' # assuming cookie was set using the same salt
>>> request.get_signed_cookie("nonexistent-cookie")
KeyError: 'nonexistent-cookie'
>>> request.get_signed_cookie("nonexistent-cookie", False)
False
>>> request.get_signed_cookie("cookie-that-was-tampered-with")
BadSignature: ...
>>> request.get_signed_cookie("name", max_age=60)
SignatureExpired: Signature age 1677.3839159 > 60 seconds
>>> request.get_signed_cookie("name", False, max_age=60)
False

Смотрите криптографическая подпись для получения дополнительной информации.

HttpRequest.is_secure()[исходный код]

Возвращает True, если запрос безопасен; то есть, если это было сделано с HTTPS.

HttpRequest.accepts(mime_type)[исходный код]

Возвращает True, если заголовок запроса Accept совпадает с аргументом mime_type:

>>> request.accepts("text/html")
True

Большинство браузеров по умолчанию отправляют Accept: */*, поэтому для всех типов содержимого будет возвращено True. Установка явного заголовка Accept в запросах API может быть полезна для возврата другого типа контента только для этих потребителей. Смотрите Пример переговоров по содержанию для использования accepts() для возврата различного контента потребителям API.

Если ответ зависит от содержимого заголовка Accept и вы используете какую-либо форму кеширования, например, в Django cache middleware, вам следует декорировать представление с помощью var_on_headers('Accept'), чтобы ответы правильно кэшировались.

HttpRequest.read(size=None)[исходный код]
HttpRequest.readline()[исходный код]
HttpRequest.readlines()[исходный код]
HttpRequest.__iter__()[исходный код]

Методы, реализующие файловый интерфейс для чтения из экземпляра HttpRequest. Это позволяет обрабатывать входящий запрос в потоковом режиме. Распространенным вариантом использования будет обработка больших полезных данных XML с помощью итеративного синтаксического анализатора без построения всего XML-дерева в памяти.

Учитывая этот стандартный интерфейс, экземпляр HttpRequest может быть передан непосредственно в синтаксический анализатор XML, например ElementTree:

import xml.etree.ElementTree as ET

for element in ET.iterparse(request):
    process(element)

Объекты QueryDict

class QueryDict[исходный код]

В объекте HttpRequest атрибуты GET и POST являются экземплярами django.http.QueryDict, настроенного класса, подобного словарю для работы с несколькими значениями одного и того же ключа. Это необходимо, поскольку некоторые элементы HTML-формы, в частности <select multiple>, передают несколько значений для одного и того же ключа.

QueryDict в request.POST и request.GET будут неизменными при доступе в обычном цикле запрос/ответ. Чтобы получить изменяемую версию, вам нужно использовать QueryDict.copy().

Методы

QueryDict реализует все стандартные методы словаря, потому что это подкласс словаря. Здесь указаны исключения:

QueryDict.__init__(query_string=None, mutable=False, encoding=None)[исходный код]

Создает экземпляр объекта QueryDict на основе query_string.

>>> QueryDict("a=1&a=2&c=3")
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

Если query_string не передан, результирующий QueryDict будет пустым (у него не будет ключей или значений).

Большинство QueryDict, с которыми вы столкнетесь, и в частности те, которые находятся в request.POST и request.GET, будут неизменными. Если вы создаете один экземпляр самостоятельно, вы можете сделать его изменяемым, передав ему mutable=True в его ``__init__().

Строки для установки ключей и значений будут преобразованы из encoding в str. Если encoding не установлен, по умолчанию используется DEFAULT_CHARSET.

classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)[исходный код]

Создает новый QueryDict с ключами из iterable и каждым значением, равным value. Например:

>>> QueryDict.fromkeys(["a", "a", "b"], value="val")
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>
QueryDict.__getitem__(key)

Возвращает значение для данного ключа. Если ключ имеет более одного значения, он возвращает последнее значение. Вызывает django.utils.datastructures.MultiValueDictKeyError, если ключ не существует. (Это подкласс Python KeyError, поэтому вы можете придерживаться перехвата KeyError.)

QueryDict.__setitem__(key, value)[исходный код]

Устанавливает для данного ключа значение [значение] (список, единственным элементом которого является значение). Обратите внимание, что это, как и другие словарные функции, которые имеют побочные эффекты, можно вызывать только в изменяемом QueryDict (например, в том, который был создан с помощью QueryDict.copy()).

QueryDict.__contains__(key)

Возвращает True, если заданный ключ установлен. Это позволяет вам сделать, например, if "foo" in request.GET.

QueryDict.get(key, default=None)

Использует ту же логику, что и __getitem__(), с ловушкой для возврата значения по умолчанию, если ключ не существует.

QueryDict.setdefault(key, default=None)[исходный код]

Как dict.setdefault(), за исключением того, что он использует __setitem__() внутри.

QueryDict.update(other_dict)

Принимает либо QueryDict, либо словарь. Аналогично dict.update(), за исключением того, что он применяется к текущим элементам словаря, а не заменяет их. Например:

>>> q = QueryDict("a=1", mutable=True)
>>> q.update({"a": "2"})
>>> q.getlist("a")
['1', '2']
>>> q["a"]  # returns the last
'2'
QueryDict.items()

Аналогично dict.items(), только здесь используется та же логика последнего значения, что и в __getitem__(), и возвращается объект-итератор вместо объекта представления. Например:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.items())
[('a', '3')]
QueryDict.values()

Аналогично dict.values(), только здесь используется та же логика последнего значения, что и в __getitem__(), и возвращается итератор, а не объект представления. Например:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.values())
['3']

Кроме того, QueryDict имеет следующие методы:

QueryDict.copy()[исходный код]

Возвращает копию объекта, используя copy.deepcopy(). Эта копия будет изменяемой, даже если оригинал не был.

QueryDict.getlist(key, default=None)

Возвращает список данных с запрошенным ключом. Возвращает пустой список, если ключ не существует, а default равен None. Гарантируется возврат списка, если только указанное по умолчанию значение не является списком.

QueryDict.setlist(key, list_)[исходный код]

Устанавливает для данного ключа значение list_ (в отличие от __setitem__()).

QueryDict.appendlist(key, item)[исходный код]

Добавляет элемент во внутренний список, связанный с ключом.

QueryDict.setlistdefault(key, default_list=None)[исходный код]

Например setdefault(), за исключением того, что он принимает список значений вместо одного значения.

QueryDict.lists()

Подобно items(), за исключением того, что включает все значения, в виде списка, для каждого члена словаря. Например:

>>> q = QueryDict("a=1&a=2&a=3")
>>> q.lists()
[('a', ['1', '2', '3'])]
QueryDict.pop(key)[исходный код]

Возвращает список значений для заданного ключа и удаляет их из словаря. Вызывает ошибку KeyError, если ключ не существует. Например:

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.pop("a")
['1', '2', '3']
QueryDict.popitem()[исходный код]

``KeyError``Удаляет произвольный член словаря (поскольку нет понятия упорядочивания), а возвращает кортеж из двух значений, содержащий ключ и список всех значений для ключа. […] […]

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])
QueryDict.dict()

Возвращает представление dict в виде QueryDict. QueryDict dict QueryDict.__getitem__() F

>>> q = QueryDict("a=1&a=3&a=5")
>>> q.dict()
{'a': '5'}
QueryDict.urlencode(safe=None)[исходный код]

Возвращает строку данных в формате строки запроса. Например:

>>> q = QueryDict("a=2&b=3&b=5")
>>> q.urlencode()
'a=2&b=3&b=5'

Для передачи символов, не требующих кодирования, используйте параметр safe. Например:

>>> q = QueryDict(mutable=True)
>>> q["next"] = "/a&b/"
>>> q.urlencode(safe="/")
'next=/a%26b/'

Объекты HttpResponse

class HttpResponse[исходный код]

В отличие от объектов HttpRequest, которые автоматически создаются Django, ответственность за объекты HttpResponse лежит на вас. Каждое написанное вами представление отвечает за создание, заполнение и возврат HttpResponse.

Класс HttpResponse находится в модуле django.http.

Применение

Передача строк

Обычно в конструктор HttpResponse передается содержимое страницы в виде строки, байтстринга или memoryview:

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")
>>> response = HttpResponse(b"Bytestrings are also accepted.")
>>> response = HttpResponse(memoryview(b"Memoryview as well."))

Если же требуется добавлять содержимое постепенно, то в качестве файлоподобного объекта можно использовать response:

>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

Передача итераторов

Наконец, вы можете передать HttpResponse итератор, а не строки. HttpResponse немедленно использует итератор, сохраняет его содержимое в виде строки и отбрасывает его. Объекты с методом close(), такие как файлы и генераторы, немедленно закрываются.

Если вам нужно, чтобы ответ передавался от итератора клиенту, вы должны вместо этого использовать класс StreamingHttpResponse.

Настройка полей заголовка

Чтобы установить или удалить поле заголовка в ответе, используйте HttpResponse.headers:

>>> response = HttpResponse()
>>> response.headers["Age"] = 120
>>> del response.headers["Age"]

Вы также можете манипулировать заголовками, рассматривая свой ответ как словарь:

>>> response = HttpResponse()
>>> response["Age"] = 120
>>> del response["Age"]

Это прокси для HttpResponse.headers и является исходным интерфейсом, предлагаемым HttpResponse.

При использовании этого интерфейса, в отличие от словаря, del не вызывает KeyError, если поле заголовка не существует.

Также можно установить заголовки при инстанцировании:

>>> response = HttpResponse(headers={"Age": 120})

Для настройки полей заголовка Cache-Control и Vary рекомендуется использовать patch_cache_control() и patch_vary_headers() из django.utils.cache, поскольку эти поля могут иметь несколько значений, разделенных запятыми. Методы «patch» гарантируют, что другие значения, например добавленные промежуточным программным обеспечением, не удаляются.

Поля заголовка HTTP не могут содержать символы новой строки. Попытка установить поле заголовка, содержащее символ новой строки (CR или LF), вызовет ошибку BadHeaderError

Указание браузеру рассматривать ответ как вложение файла

Чтобы указать браузеру, что ответ следует рассматривать как файловое вложение, установите заголовки Content-Type и Content-Disposition. Например, так можно вернуть электронную таблицу Microsoft Excel:

>>> response = HttpResponse(
...     my_data,
...     headers={
...         "Content-Type": "application/vnd.ms-excel",
...         "Content-Disposition": 'attachment; filename="foo.xls"',
...     },
... )

В заголовке Content-Disposition нет ничего специфичного для Django, но его синтаксис легко забыть, поэтому мы включили его здесь.

Атрибуты

HttpResponse.content

Строка байтов, представляющая содержимое, при необходимости закодированное из строки.

HttpResponse.cookies

Объект http.cookies.SimpleCookie, содержащий файлы cookie, включенные в ответ.

HttpResponse.headers

Нечувствительный к регистру диктоподобный объект, который предоставляет интерфейс для всех заголовков HTTP в ответе, кроме заголовка Set-Cookie. См. Настройка полей заголовка и HttpResponse.cookies.

HttpResponse.charset

Строка, обозначающая кодировку, в которой будет закодирован ответ. Если не задан во время создания экземпляра HttpResponse, он будет извлечен из content_type, и если это не удастся, будет использоваться параметр DEFAULT_CHARSET.

HttpResponse.status_code

HTTP status code для ответа.

Если явно не задано reason_phrase, изменение значения status_code вне конструктора также изменит значение reason_phrase.

HttpResponse.reason_phrase

Фраза причины ответа по протоколу HTTP. Используется стандартная фраза причины HTTP standard’s.

Если явно не установлено, reason_phrase определяется значением status_code.

HttpResponse.streaming

Это всегда False.

Этот атрибут существует, поэтому промежуточное ПО может обрабатывать потоковые ответы иначе, чем обычные ответы.

HttpResponse.closed

True`, если ответ был закрыт.

Методы

HttpResponse.__init__(content=b'', content_type=None, status=200, reason=None, charset=None, headers=None)[исходный код]

Создает экземпляр объекта HttpResponse с заданным содержимым страницы, типом содержимого и заголовками.

content чаще всего представляет собой итератор, строку байтов, memoryview или строку. Другие типы будут преобразованы в байтовую строку путем кодирования их строкового представления. Итераторы должны возвращать строки или байтовые строки, и они будут объединены вместе для формирования содержимого ответа.

content_type - это тип MIME, который может быть дополнен кодировкой набора символов и используется для заполнения заголовка HTTP Content-Type. Если не указано, он формируется из 'text/html' и настроек DEFAULT_CHARSET, по умолчанию: "text/html; charset=utf-8".

status - это HTTP status code для ответа. Для значимых псевдонимов, таких как HTTPStatus.NO_CONTENT, можно использовать питоновские http.HTTPStatus.

reason - это фраза ответа HTTP. Если не указан, будет использоваться фраза по умолчанию.

charset - кодировка, в которой будет закодирован ответ. Если не задан, он будет извлечен из content_type, и если это не удастся, будет использована настройка DEFAULT_CHARSET.

headers - это dict заголовков HTTP для ответа.

HttpResponse.__setitem__(header, value)

Устанавливает заданное имя заголовка в заданное значение. header и value должны быть строками.

HttpResponse.__delitem__(header)

Удаляет заголовок с заданным именем. Если заголовок не существует, происходит автоматическая ошибка. Без учета регистра.

HttpResponse.__getitem__(header)

Возвращает значение для заданного имени заголовка. Без учета регистра.

HttpResponse.get(header, alternate=None)

Возвращает значение для данного заголовка или alternate, если заголовок не существует.

HttpResponse.has_header(header)

Возвращает True или False на основе проверки без учета регистра для заголовка с заданным именем.

HttpResponse.items()

Действует как dict.items() для заголовков HTTP в ответе.

HttpResponse.setdefault(header, value)

Устанавливает заголовок, если он еще не установлен.

Устанавливает cookie. Параметры такие же, как и в объекте cookie Morsel в стандартной библиотеке Python.

  • max_age должен быть объектом timedelta, целым числом секунд, или None (по умолчанию), если cookie должен длиться только до тех пор, пока длится сессия браузера клиента. Если expires не указано, оно будет вычислено.

  • expires должен быть строкой в формате "Wdy, DD-Mon-YY HH:MM:SS GMT" или объектом datetime.datetime в формате UTC. Если expires является объектом datetime, будет вычислено max_age.

  • Используйте domain, если хотите установить междоменный файл cookie. Например, domain="example.com" установит файл cookie, доступный для чтения доменам www.example.com, blog.example.com и т.д. В противном случае файл cookie будет доступен для чтения только домену, который установить его.

  • Используйте secure=True, если вы хотите, чтобы cookie отправлялся на сервер только при запросе по схеме ``https.

  • Используйте httponly=True, если вы хотите запретить клиентскому JavaScript доступ к cookie.

    HttpOnly - это флаг, включенный в заголовок HTTP-ответа Set-Cookie. Это часть стандарта RFC 6265 для файлов cookie и может быть полезным способом снизить риск доступа сценария на стороне клиента к защищенным данным файлов cookie.

  • Используйте samesite='Strict' или samesite='Lax', чтобы указать браузеру не отправлять этот файл cookie при выполнении запроса из разных источников. SameSite поддерживается не всеми браузерами, поэтому он не заменяет защиту Django от CSRF, а, скорее, обеспечивает глубокую защиту.

    Используйте samesite='None' (строка), чтобы явно указать, что этот файл cookie отправляется со всеми запросами на одном сайте и между сайтами.

Предупреждение

RFC 6265 утверждает, что пользовательские агенты должны поддерживать файлы cookie размером не менее 4096 байт. Для многих браузеров это также максимальный размер. Django не вызовет исключение, если есть попытка сохранить cookie размером более 4096 байт, но многие браузеры не будут правильно устанавливать cookie.

Аналогичен set_cookie(), но криптографически подписывает cookie перед его установкой. Используйте вместе с HttpRequest.get_signed_cookie(). Вы можете использовать необязательный аргумент salt для добавления силы ключа, но вам нужно будет не забыть передать его в соответствующий вызов HttpRequest.get_signed_cookie().

Удаляет куки с заданным ключом. Если ключ не существует, то никаких ошибок не вызывает.

Из-за того, как работают файлы cookie, для параметров path и domain должны быть те же значения, которые вы использовали в set_cookie() - в противном случае файл cookie не может быть удален.

HttpResponse.close()

Этот метод вызывается в конце запроса непосредственно сервером WSGI.

HttpResponse.write(content)[исходный код]

Этот метод делает экземпляр HttpResponse файловым объектом.

HttpResponse.flush()

Этот метод делает экземпляр HttpResponse файловым объектом.

HttpResponse.tell()[исходный код]

Этот метод делает экземпляр HttpResponse файловым объектом.

HttpResponse.getvalue()[исходный код]

Возвращает значение HttpResponse.content. Этот метод делает экземпляр HttpResponse подобным потоку объектом.

HttpResponse.readable()

Всегда False. Этот метод делает экземпляр HttpResponse подобным потоку объектом.

HttpResponse.seekable()

Всегда False. Этот метод делает экземпляр HttpResponse подобным потоку объектом.

HttpResponse.writable()[исходный код]

Всегда True. Этот метод делает экземпляр HttpResponse подобным потоку объектом.

HttpResponse.writelines(lines)[исходный код]

Записывает в ответ список строк. Разделители строк не добавляются. Этот метод делает экземпляр HttpResponse подобным потоку объектом.

Подклассы HttpResponse

Django включает несколько подклассов HttpResponse, которые обрабатывают различные типы HTTP-ответов. Как и HttpResponse, эти подклассы находятся в django.http.

class HttpResponseRedirect[исходный код]

Первый аргумент конструктора обязателен - путь для перенаправления. Это может быть полный URL-адрес (например, 'https://www.yahoo.com/search/'), абсолютный путь без домена (например, '/search/') или даже относительный путь (например, 'search/'). В этом последнем случае браузер клиента восстановит сам полный URL-адрес в соответствии с текущим путем. Смотрите HttpResponse для других необязательных аргументов конструктора. Обратите внимание, что это возвращает код состояния HTTP 302.

url

Этот доступный только для чтения атрибут представляет URL-адрес, на который будет перенаправлен ответ (эквивалент заголовка ответа Location).

class HttpResponsePermanentRedirect[исходный код]

Как и HttpResponseRedirect, но он возвращает постоянное перенаправление (код статуса HTTP 301) вместо «found» перенаправления (код статуса 302).

class HttpResponseNotModified[исходный код]

Конструктор не принимает никаких аргументов, и к этому ответу не следует добавлять содержимое. Используйте, чтобы указать, что страница не изменялась с момента последнего запроса пользователя (код состояния 304).

class HttpResponseBadRequest[исходный код]

Действует так же, как HttpResponse, но использует код состояния 400.

class HttpResponseNotFound[исходный код]

Действует так же, как HttpResponse, но использует код состояния 404.

class HttpResponseForbidden[исходный код]

Действует так же, как HttpResponse, но использует код состояния 403.

class HttpResponseNotAllowed[исходный код]

Как и HttpResponse, но использует код состояния 405. Первый аргумент конструктора обязателен: список разрешенных методов (например, ['GET', 'POST']).

class HttpResponseGone[исходный код]

Действует так же, как HttpResponse, но использует код состояния 410.

class HttpResponseServerError[исходный код]

Действует так же, как HttpResponse, но использует код состояния 500.

Примечание

Если пользовательский подкласс HttpResponse реализует метод render, Django будет рассматривать его как эмуляцию SimpleTemplateResponse, а метод render должен сам возвращает действительный объект ответа.

Пользовательские классы ответа

Если вам понадобится класс ответа, который Django не предоставляет, вы можете создать его с помощью http.HTTPStatus. Например:

from http import HTTPStatus
from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

Объекты JsonResponse

class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)[исходный код]

Подкласс HttpResponse, который помогает создавать ответ в формате JSON. Он наследует большую часть поведения от своего суперкласса с несколькими отличиями:

Его заголовок Content-Type по умолчанию имеет значение application/json.

Первый параметр, data, должен быть экземпляром dict. Если для параметра safe установлено значение False (смотрите ниже), это может быть любой JSON-сериализуемый объект.

Энкодер, по умолчанию :class:django.core.serializers.json.DjangoJSONEncoder, будет использоваться для сериализации данных. Смотрите JSON сериализация для получения дополнительных сведений об этом сериализаторе.

Логический параметр safe по умолчанию имеет значение True. Если установлено значение False, для сериализации можно передать любой объект (в противном случае разрешены только экземпляры dict). Если safe имеет значение True, а в качестве первого аргумента передается объект, отличный от dict, то будет вызвана ошибка :exc:TypeError.

Параметр json_dumps_params - это словарь аргументов для передачи в вызов json.dumps(), используемый для генерации ответа.

Применение

Типичный вариант использования может выглядеть следующим образом:

>>> from django.http import JsonResponse
>>> response = JsonResponse({"foo": "bar"})
>>> response.content
b'{"foo": "bar"}'

Сериализация не словарных объектов

Для сериализации объектов, отличных от dict, необходимо установить параметр safe в значение False:

>>> response = JsonResponse([1, 2, 3], safe=False)

Если не передать safe=False, будет вызвана ошибка :exc:TypeError.

Обратите внимание, что API, основанный на объектах dict, является более расширяемым, гибким и позволяет легче поддерживать совместимость с форвардами. Поэтому следует избегать использования объектов non-dict в JSON-кодированном ответе.

Предупреждение

До появления 5th edition of ECMAScript можно было отравить конструктор JavaScript Array. По этой причине Django по умолчанию не позволяет передавать в конструктор JsonResponse объекты не-dict. Однако большинство современных браузеров используют ECMAScript 5, который устраняет этот вектор атаки. Поэтому можно отключить эту меру предосторожности.

Изменение кодировщика JSON по умолчанию

Если необходимо использовать другой класс JSON-кодировщика, то в метод конструктора можно передать параметр encoder:

>>> response = JsonResponse(data, encoder=MyJSONEncoder)

Объекты StreamingHttpResponse

class StreamingHttpResponse[исходный код]

Класс StreamingHttpResponse используется для передачи ответа из Django в браузер.

Расширенное использование

StreamingHttpResponse является несколько расширенным, поскольку важно знать, как будет обслуживаться приложение: синхронно в WSGI или асинхронно в ASGI, и соответствующим образом настроить его использование.

Пожалуйста, читайте эти примечания с осторожностью.

Примером использования StreamingHttpResponse в WSGI является потоковая передача контента, когда генерация ответа занимает слишком много времени или использует слишком много памяти. Например, это полезно для generating large CSV files.

Однако при этом есть соображения, связанные с производительностью. Django под WSGI рассчитан на короткие запросы. Потоковые ответы будут привязывать рабочий процесс на все время выполнения ответа. Это может привести к снижению производительности.

Как правило, дорогостоящие задачи лучше выполнять вне цикла «запрос - ответ», а не прибегать к потоковому ответу.

Однако при обслуживании по протоколу ASGI запрос StreamingHttpResponse не должен останавливать обслуживание других запросов в ожидании ввода-вывода. Это открывает возможность использования долгоживущих запросов для потоковой передачи контента и реализации таких паттернов, как long-polling и server-sent events.

Даже в соответствии с примечанием ASGI, StreamingHttpResponse следует использовать только в ситуациях, когда абсолютно необходимо, чтобы перед передачей данных клиенту не происходило итерации всего содержимого. Из-за невозможности доступа к содержимому многие промежуточные программы не могут нормально функционировать. Например, заголовки ETag и Content-Length не могут быть сгенерированы для потоковых ответов.

StreamingHttpResponse не является подклассом HttpResponse, потому что он имеет немного другой API. Однако он почти идентичен со следующими заметными отличиями:

  • Ему должен быть задан итератор, выдающий в качестве содержимого байтстринги, memoryview или строки. При работе с WSGI это должен быть синхронный итератор. При работе с ASGI это должен быть асинхронный итератор.

  • Вы можете […]

    В WSGI ответ будет итерироваться синхронно. В ASGI ответ будет итерироваться асинхронно. (Именно поэтому тип итератора должен соответствовать используемому протоколу).

    Чтобы избежать сбоя, неправильный тип итератора будет сопоставлен правильному типу во время итерации, о чем будет выдано предупреждение, но для этого итератор должен быть полностью поглощен, что лишает смысла использование StreamingHttpResponse вообще.

  • Он не имеет атрибута content. Вместо этого у него есть атрибут streaming_content. Он может быть использован в промежуточном ПО для обертывания итерабельной переменной ответа, но не должен использоваться.

  • Вы не можете использовать методы файлового объекта tell() или write(). Это вызовет исключение.

Базовый класс HttpResponseBase является общим между HttpResponse и StreamingHttpResponse.

Changed in Django 4.2:

Добавлена поддержка асинхронной итерации.

Атрибуты

StreamingHttpResponse.streaming_content

Итератор содержимого ответа, строка байтов, закодированная в соответствии с HttpResponse.charset.

StreamingHttpResponse.status_code

HTTP status code для ответа.

Если явно не задано reason_phrase, изменение значения status_code вне конструктора также изменит значение reason_phrase.

StreamingHttpResponse.reason_phrase

Фраза причины ответа по протоколу HTTP. Используется стандартная фраза причины HTTP standard’s.

Если явно не установлено, reason_phrase определяется значением status_code.

StreamingHttpResponse.streaming

Это всегда True.

StreamingHttpResponse.is_async
New in Django 4.2.

Булево число, указывающее, является ли StreamingHttpResponse.streaming_content асинхронным итератором или нет.

Это полезно для промежуточного ПО, которому необходимо обернуть StreamingHttpResponse.streaming_content.

Обработка разъединений

New in Django 5.0.

Если клиент отключится во время потокового ответа, Django отменит корутину, обрабатывающую ответ. Если вы хотите очистить ресурсы вручную, вы можете сделать это, перехватив asyncio.CancelledError:

async def streaming_response():
    try:
        # Do some work here
        async for chunk in my_streaming_iterator():
            yield chunk
    except asyncio.CancelledError:
        # Handle disconnect
        ...
        raise


async def my_streaming_view(request):
    return StreamingHttpResponse(streaming_response())

В этом примере показано, как обрабатывать отсоединение клиента во время передачи ответа. Если вы выполняете длительные операции в представлении перед возвратом объекта StreamingHttpResponse, то вам может понадобиться сам handle disconnections in the view.

Объекты FileResponse

class FileResponse(open_file, as_attachment=False, filename='', **kwargs)[исходный код]

FileResponse является подклассом StreamingHttpResponse, оптимизированным для двоичных файлов. Он использует wsgi.file_wrapper, если он предоставляется сервером wsgi, в противном случае он передает файл небольшими порциями.

Если as_attachment=True, заголовок Content-Disposition устанавливается в attachment, который просит браузер предложить файл пользователю для загрузки. В противном случае заголовок Content-Disposition со значением inline (по умолчанию браузер) будет установлен только в том случае, если имя файла доступно.

Если у open_file нет имени или если open_file имя не подходит, укажите собственное имя файла с помощью параметра filename. Обратите внимание, что если вы передадите файловый объект, такой как io.BytesIO, ваша задача - seek() перед передачей его FileResponse.

Заголовок Content-Length устанавливается автоматически, если о нем можно догадаться по содержимому open_file.

Заголовок Content-Type устанавливается автоматически, если о нем можно догадаться по filename, или по имени open_file.

FileResponse принимает любой файлоподобный объект с двоичным содержимым, например, файл, открытый в двоичном режиме следующим образом:

>>> from django.http import FileResponse
>>> response = FileResponse(open("myfile.png", "rb"))

Файл будет закрыт автоматически, поэтому не открывайте его с помощью диспетчера контекста.

Использование в рамках ASGI

Файловый API языка Python является синхронным. Это означает, что для обслуживания файла по протоколу ASGI он должен быть полностью обработан.

Для асинхронной передачи файла необходимо использовать сторонний пакет, предоставляющий асинхронный файловый API, например aiofiles.

Методы

FileResponse.set_headers(open_file)[исходный код]

Этот метод автоматически вызывается во время инициализации ответа и устанавливает различные заголовки (Content-Length, Content-Type и Content-Disposition) в зависимости от open_file.

HttpResponseBase класс

class HttpResponseBase[исходный код]

Класс HttpResponseBase является общим для всех ответов Django. Его не следует использовать для создания ответов напрямую, но он может быть полезен для проверки типов.

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