• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

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

Быстрый обзор

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

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

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

Объект HttpRequest

class HttpRequest

Атрибуты

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

HttpRequest.scheme

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

HttpRequest.body

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

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

HttpRequest.path

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

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

HttpRequest.path_info

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

Например, если WSGIScriptAlias равен "/minfo", атрибут path может быть равен "/minfo/music/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

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

HttpRequest.content_params

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

HttpRequest.GET

Объект с интерфейсом словаря, который содержит HTTP GET параметры. Смотрите описание QueryDict ниже.

HttpRequest.POST

Объект-словарь содержащий все POST параметры, переданные формой. Смотрите описание QueryDict ниже. Если вам необходимо получить необработанные данные или данные переданные не через форму, используйте атрибут HttpRequest.body.

Запрос может использовать метод POST но содержать пустой словарь POST – например, форма была передана через POST HTTP метод, но не содержала никаких данных. Поэтому, вы не должны использовать if request.POST для проверки был ли использован метод POST; вместо этого используйте if request.method == "POST" (смотрите ниже).

Заметим: POST не содержит информацию о загруженных файлах. Смотрите FILES.

HttpRequest.COOKIES

Словарь Python содержащий все «cookie». Ключи и значения являются строками.

HttpRequest.FILES

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

Подробности в разделе Управление файлами.

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

HttpRequest.META

Словарь Python содержащий все доступные 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

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

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

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

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

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

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

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

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

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

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

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

HttpRequest.current_app

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

HttpRequest.urlconf

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

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

HttpRequest.exception_reporter_filter

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

HttpRequest.exception_reporter_class

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

Атрибуты, которые устанавливаются промежуточным слоем(middleware)

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

HttpRequest.session

Добавляется SessionMiddleware: объект с интерфейсом словаря, который содержит текущую сессию.

HttpRequest.site

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

HttpRequest.user

Добавляется AuthenticationMiddleware: содержит объект AUTH_USER_MODEL представляющий текущего пользователя. Если пользователь не авторизирован, атрибут user будет содержать django.contrib.auth.models.AnonymousUser. Вы можете различить их используя is_authenticated():

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

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

Методы

HttpRequest.auser()

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

HttpRequest.get_host()

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

Например: "127.0.0.1:8000"

Вызывает django.core.Exceptions.DisallowedHost, если хост не находится в ALLOWED_HOSTS или имя домена недействительно в соответствии с RFC 1034/1035.

Примечание

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

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

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

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

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

HttpRequest.get_port()

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

HttpRequest.get_full_path()

Возвращает path, со строкой запроса, если она присутствует.

Например: "/music/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)

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

Если location уже является абсолютным 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.

Возвращает значение подписанных(signed) cookie, или вызывает исключение django.core.signing.BadSignature если подпись не верна. При передаче аргумента default исключение не будет вызвано и функция вернет значение по-умолчанию.

Необязательный аргумент salt может быть использован для дополнительной защиты от « brute force» атак. Если передан аргумент 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)
New in 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 Section 12.5.1.)

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

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

Примечание

Если ответ варьируется в зависимости от содержимого заголовка Accept, и вы используете какую-либо форму кэширования, такую ​​как Django cache middleware, вам следует украсить представление 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 – неизменяемы. Чтобы получить изменяемую версию, используйте .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, которые используются в Django, в том числе request.POST и request.GET, будут неизменяемыми. Если вы создаете экземпляр самостоятельно, можете сделать его изменяемым, передав mutable=True в __init__().

Строки ключей и значений будут преобразованы в unicode с использованием encoding. Если 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] (список Python с единственным элементом value). Заметим, что это, так же как и другие методы словаря изменяющие значения, могут быть вызваны только для изменяемого объекта QueryDict (который был создан через copy()).

QueryDict.__contains__(key)

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

QueryDict.get(key, default=None)

Аналогичен методу __getitem__(), но возвращает значение по-умолчанию вместо исключения, если ключ не существует.

QueryDict.setdefault(key, default=None)

Аналогичен методу 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() из стандартных библиотек Python. Копия будет изменяемая, даже если оригинал не был.

QueryDict.getlist(key, default=None)

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

QueryDict.setlist(key, list_)

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

QueryDict.appendlist(key, item)

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

QueryDict.setlistdefault(key, default_list=None)

Аналогичен setdefault, но принимает список значений, а не одно значение.

QueryDict.lists()

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

>>> q = QueryDict("a=1&a=2&a=3")
>>> q.lists()
[('a', ['1', '2', '3'])]
QueryDict.pop(key)

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

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

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

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

Возвращает представление dict для QueryDict. Для каждой пары (ключ, список) в QueryDict, dict будет содержать (ключ, элемент), где item — один элемент списка, используя ту же логику, что и 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.

Использование

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

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

>>> 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 сразу выполнит итератор и сохранит результат как строку.

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

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

Байтовое представление содержимого, закодированное с объекта Unicode при необходимости.

HttpResponse.text
New in Django 5.2.

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

HttpResponse.cookies

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

HttpResponse.headers

Нечувствительный к регистру объект, подобный dict, который предоставляет интерфейс для всех 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. Он использует фразы причины по умолчанию <9110#section-15.1>стандарта HTTP.

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

HttpResponse.streaming

Всегда False.

Указывает middleware, что этот ответ потоковый и его нужно обрабатывать не так, как обычные запросы.

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 - кодировка, в которую будет закодирован ответ. Если не указана во время создания объекта HttpResponse, будет проверятся content_type, и если не будет найдена, будет использоваться значение настройки DEFAULT_CHARSET.

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

HttpResponse.__setitem__(header, value)

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

HttpResponse.__delitem__(header)

Удаляет заголовок ответа. Не вызывает исключения, если заголовок не существует. Регистронезависимый.

HttpResponse.__getitem__(header)

Возвращает значение заголовка. Регистрозависимый.

HttpResponse.get(header, alternate=None)

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

HttpResponse.has_header(header)

Возвращает True или False в результате регистронезависимого поиска заголовка по указанному названию.

HttpResponse.items()

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

HttpResponse.setdefault(header, value)

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

Устанавливает 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=".lawrence.com" установит cookie доступные для доменов www.lawrence.com, blogs.lawrence.com и calendars.lawrence.com. Иначе, cookie будут доступны только для текущего домена.

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

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

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

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

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

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

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

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

Удаляет cookie. Не вызывает исключения, если cookie не существует.

Учитывая механизм работы cookie, значения path и domain должны быть такими же, какие использовались при вызове set_cookie() – в противном случае cookie могут быть не удалены.

HttpResponse.close()

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

HttpResponse.write(content)

Метод для соблюдения интерфейса объекта файла.

HttpResponse.flush()

Метод для соблюдения интерфейса объекта файла.

HttpResponse.tell()

Метод для соблюдения интерфейса объекта файла.

HttpResponse.getvalue()

Возвращает значение HttpResponse.content. Этот метод позволяет использовать HttpResponse как объект-файл.

HttpResponse.readable()

Всегда True. Этот метод позволяет использовать HttpResponse как объект-файл.

HttpResponse.seekable()

Всегда True. Этот метод позволяет использовать 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).

Changed in Django 5.2:

Был добавлен аргумент preserve_request.

class HttpResponsePermanentRedirect

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

Changed in 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 должен возвращать правильный объект ответа.

Подклассы HttpResponse

Если вам нужен класс ответа, которого нет в 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 должен быть словарем. Если параметр safe равен False (смотрите ниже), может принимать любой объект, который можно преобразовать в JSON.

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

Параметр safe по умолчанию равен True. Если равен False, можно передать любой объект для преобразования в JSON (иначе – только 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. Он использует фразы причины по умолчанию <9110#section-15.1>стандарта 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, то вы также можете захотеть обрабатывать отключения в самом представлении <async-handling-disconnect>`.

Объекты 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.

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

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

Back to Top