Объекты запросов и ответов
Краткий обзор
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будет сопоставлен ключуMETAHTTP_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_PORTMETAименно в таком порядке.
-
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 middlewareDjango, следует декорировать представление с помощью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, если ключ не существует. (Это подкласс стандартного исключения PythonKeyError, поэтому можно перехватывать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, при необходимости дополненный кодировкой символов; он используется для заполнения заголовка HTTPContent-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/