Spec-Zone.ru › Django 6.0

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

Краткий обзор

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 может упростить перенос кода между тестовым и рабочим серверами.

Например, если для вашего приложения задано значение "/minfo" в WSGIScriptAlias, то path может быть равен "/minfo/music/bands/the_beatles/", а path_info будет равен "/music/bands/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 — например, если форма запрошена с помощью HTTP-метода POST, но не содержит данных формы. Поэтому не следует использовать if request.POST для проверки, используется ли метод POST; вместо этого используйте if request.method == "POST" (см. HttpRequest.method).

POST не содержит информацию о загруженных файлах. См. 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-заголовок Host, отправленный клиентом.
  • HTTP_REFERER — страница-источник, если она есть.
  • HTTP_USER_AGENT — строка 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 [исходный код]

Объект, подобный словарю, нечувствительный к регистру, который предоставляет доступ ко всем заголовкам запроса с префиксом 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. Это означает, что он доступен во всех представлениях, но не в промежуточном ПО, выполняемом до разрешения 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. Подробнее см. в разделе Пользовательские отчёты об ошибках.

Атрибуты, задаваемые промежуточным ПО

Некоторые классы промежуточного ПО из приложений Django contrib задают атрибуты запроса. Если атрибут отсутствует в запросе, проверьте, указан ли соответствующий класс промежуточного ПО в 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()

Из AuthenticationMiddleware: сопрограмма. Возвращает экземпляр 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() не работает, если между хостом и сервером находится несколько прокси. Один из вариантов решения — использовать промежуточное ПО для перезаписи заголовков прокси, как показано в примере ниже:

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, при необходимости добавляя строку запроса.

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

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

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

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

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

Возвращает location в виде абсолютного URI. Если расположение не указано, в качестве расположения будет использовано 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.

HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) [исходный код]

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

Необязательный аргумент salt можно использовать для дополнительной защиты от атак методом перебора, направленных на ваш секретный ключ. Если он указан, аргумент max_age будет сравнен с подписанной временной меткой, прикреплённой к значению cookie, чтобы убедиться, что срок существования cookie не превышает 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.get_preferred_type(media_types) [исходный код]
Новое в Django 5.2.

Возвращает предпочтительный MIME-тип из media_types на основе заголовка Accept или None, если клиент не принимает ни один из указанных типов.

Предположим, клиент отправляет заголовок Accept со значением text/html,application/json;q=0.8:

>>> request.get_preferred_type(["text/html", "application/json"])
"text/html"
>>> request.get_preferred_type(["application/json", "text/plain"])
"application/json"
>>> request.get_preferred_type(["application/xml", "text/plain"])
None

Если MIME-тип включает параметры, они также учитываются при определении предпочтительного типа медиа. Например, при заголовке Accept со значением text/vcard;version=3.0,text/html;q=0.5 возвращаемое значение request.get_preferred_type() зависит от доступных типов медиа:

>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/vcard; version=3.0",
...         "text/vcard",
...         "text/directory",
...     ]
... )
"text/vcard; version=3.0"
>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/html",
...     ]
... )
"text/html"
>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/vcard",
...         "text/directory",
...     ]
... )
None

(Подробнее о согласовании содержимого см. в разделе RFC 9110, раздел 12.5.1.)

Большинство браузеров по умолчанию отправляют Accept: */*, то есть не указывают предпочтения; в таком случае будет возвращён первый элемент в media_types.

Явная установка заголовка Accept в запросах API может быть полезна, если нужно возвращать другой тип содержимого только для этих клиентов. Пример возврата разного содержимого в зависимости от заголовка Accept см. в разделе Пример согласования содержимого.

Примечание

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

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

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

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

Большинство браузеров по умолчанию отправляют Accept: */*, поэтому для всех типов содержимого будет возвращено True.

Пример использования accepts() для возврата различного содержимого в зависимости от заголовка 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.)

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

Устанавливает для заданного ключа значение [value] (список, единственный элемент которого — 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()

Возвращает представление QueryDict в виде объекта dict. Для каждой пары (ключ, список) в QueryDict объект dict будет содержать пару (ключ, элемент), где элемент — один из элементов списка, выбранный по той же логике, что и в QueryDict.__getitem__():

>>> 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.text [источник]
Добавлено в Django 5.2.

Строковое представление HttpResponse.content, декодированное с использованием HttpResponse.charset ответа (если оно пустое, используется UTF-8).

HttpResponse.cookies

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

HttpResponse.headers

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

HttpResponse.charset

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

HttpResponse.status_code

Код состояния HTTP ответа.

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

HttpResponse.reason_phrase

Фраза причины HTTP для ответа. Используются стандартные фразы причин, предусмотренные стандартом HTTP.

Если значение 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 ответа. Для удобства можно использовать http.HTTPStatus из Python и его понятные псевдонимы, например HTTPStatus.NO_CONTENT.

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)

Задает заголовок, если он еще не был задан.

HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)

Задает файл 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. Он является частью стандарта для файлов cookie RFC 6265 и может служить полезным способом снизить риск доступа клиентского скрипта к защищенным данным файла cookie.

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

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

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

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

HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)

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

HttpResponse.delete_cookie(key, path='/', domain=None, samesite=None)

Удаляет файл 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 на основе текущего пути.

Конструктор принимает необязательный именованный аргумент preserve_request, значение которого по умолчанию равно False; в результате создается ответ с кодом состояния 302. Если preserve_request равно True, код состояния будет равен 307.

Другие необязательные аргументы конструктора см. в описании HttpResponse.

url

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

Изменено в Django 5.2:

Добавлен аргумент preserve_request.

class HttpResponsePermanentRedirect [источник]

Подобно HttpResponseRedirect, но возвращает постоянное перенаправление (код состояния HTTP 301), а не перенаправление «найдено» (код состояния 302). При preserve_request=True код состояния ответа равен 308.

Изменено в Django 5.2:

Добавлен аргумент preserve_request.

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.

Для сериализации данных будет использоваться encoder, по умолчанию — django.core.serializers.json.DjangoJSONEncoder. Подробнее об этом сериализаторе см. в разделе Сериализация JSON.

Логический параметр safe по умолчанию имеет значение True. Если он имеет значение False, для сериализации можно передать любой объект (в противном случае допускаются только экземпляры dict). Если safe имеет значение True, а в качестве первого аргумента передан объект, не являющийся dict, будет вызвано исключение 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, будет вызвано исключение TypeError.

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

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

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

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

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

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

StreamingHttpResponse объекты

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

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

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

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

Внимательно прочитайте эти примечания.

Пример использования StreamingHttpResponse в WSGI — потоковая передача содержимого, если его создание при формировании ответа заняло бы слишком много времени или потребовало бы слишком много памяти. Например, это полезно для создания больших файлов CSV.

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

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

При обслуживании через ASGI, однако, StreamingHttpResponse не обязательно мешает обслуживать другие запросы во время ожидания ввода-вывода. Это позволяет использовать длительные запросы для потоковой передачи содержимого и реализовывать такие шаблоны, как длительный опрос и отправка событий сервером.

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

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

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

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

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

  • У него нет атрибута content. Вместо него есть атрибут streaming_content. Его можно использовать в промежуточном слое для обертки итерируемого объекта ответа, но нельзя выполнять его перебор.
  • У него нет атрибута text, поскольку для его получения потребовалось бы выполнить перебор объекта ответа.
  • Нельзя использовать методы файлового объекта tell() или write(). Их вызов приведет к исключению.

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

Атрибуты

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

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

StreamingHttpResponse.status_code

Код состояния HTTP ответа.

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

StreamingHttpResponse.reason_phrase

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

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

StreamingHttpResponse.streaming

Всегда имеет значение True.

StreamingHttpResponse.is_async

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

Полезно для промежуточных слоев, которым нужно обернуть StreamingHttpResponse.streaming_content.

Обработка отключений

Если клиент отключается во время потоковой передачи ответа, 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 выполняются длительные операции, вам также может потребоваться обрабатывать отключения непосредственно в представлении.

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, перед передачей его в FileResponse вы должны самостоятельно выполнить для него seek().

Заголовок 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. Его не следует использовать для непосредственного создания ответов, но он может быть полезен для проверки типов.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/request-response/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API