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

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

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

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

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

Объекты HttpRequest

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

Атрибуты

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

HttpRequest.scheme

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

HttpRequest.body

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

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

HttpRequest.path

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

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

HttpRequest.path_info

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

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

HttpRequest.method

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

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

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

HttpRequest.content_type

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

HttpRequest.content_params

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

HttpRequest.GET

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

HttpRequest.POST

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

Возможно, что запрос может поступить через POST с пустым словарем POST - если, скажем, форма запрашивается через метод POST HTTP, но не включает данные формы. Таким образом, не следует использовать if request.POST для проверки использования метода POST; вместо этого используйте if request.method == "POST" (смотрите 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-хоста, отправляемый клиентом.
  • HTTP_REFERER – ссылающаяся страница, если есть.
  • HTTP_USER_AGENT – строка агента клиента.
  • QUERY_STRING – строка запроса в виде единственной (неанализируемой) строки.
  • REMOTE_ADDR – IP-адрес клиента.
  • REMOTE_HOST – имя хоста клиента.
  • REMOTE_USER – пользователь, аутентифицированный веб-сервером, если таковой имеется.
  • REQUEST_METHOD – строка, такая как GET или POST.
  • SERVER_NAME – имя хоста сервера.
  • SERVER_PORT – порт сервера (в виде строки).

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

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

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

HttpRequest.headers

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

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

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

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

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

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

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

{{ request.headers.user_agent }}
Changed in Django 3.0:

Добавлена поддержка поиска с использованием подчеркивания.

HttpRequest.resolver_match

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

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

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

HttpRequest.current_app

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

HttpRequest.urlconf

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

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

HttpRequest.exception_reporter_filter

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

HttpRequest.exception_reporter_class

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

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

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

HttpRequest.session

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

HttpRequest.site

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

HttpRequest.user

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

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

Методы

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

Например:

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

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

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

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

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

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

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

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

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

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

Не рекомендуется, начиная с версии 3.1.

Возвращает True, если запрос был сделан через XMLHttpRequest, проверив заголовок HTTP_X_REQUESTED_WITH для строки 'XMLHttpRequest'. Большинство современных библиотек JavaScript отправляют этот заголовок. Если вы напишете собственный вызов XMLHttpRequest (на стороне браузера), вам придется установить этот заголовок вручную, если вы хотите, чтобы работала функция is_ajax().

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

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

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

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

import xml.etree.ElementTree as ET
for element in ET.iterparse(request):
    process(element)

Объекты QueryDict

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

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

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

Методы

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

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

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

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

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

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

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

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

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

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

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

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

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

QueryDict.__contains__(key)

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

QueryDict.get(key, default=None)

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

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

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

QueryDict.update(other_dict)

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

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

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

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

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

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

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

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

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

QueryDict.getlist(key, default=None)

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

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

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

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

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

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

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

QueryDict.lists()

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

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

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

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

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

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

Возвращает представление QueryDict в виде dict. Для каждой пары (key, list) в QueryDict, у dict будет (key, 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.'))
Changed in Django 3.0:

Добавлена поддержка memoryview.

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

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

Чтобы установить или удалить поле заголовка в своем ответе, относитесь к нему как к словарю:

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

Обратите внимание, что в отличие от словаря, del не вызывает KeyError, если поле заголовка не существует.

Для настройки полей заголовка 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, content_type='application/vnd.ms-excel')
>>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'

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

Атрибуты

HttpResponse.content

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

HttpResponse.charset

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

HttpResponse.status_code

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

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

HttpResponse.reason_phrase

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

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

HttpResponse.streaming

Это всегда False.

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

HttpResponse.closed

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

Методы

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

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

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

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

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

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

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

Changed in Django 3.0:

Добавлена поддержка memoryview content.

HttpResponse.__setitem__(header, value)

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

HttpResponse.__delitem__(header)

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

HttpResponse.__getitem__(header)

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

HttpResponse.get(header, alternate=None)

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

HttpResponse.has_header(header)

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

HttpResponse.items()

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

HttpResponse.setdefault(header, value)

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

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

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

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

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

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

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

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

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

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

Changed in Django 3.1:

Было разрешено использование samesite='None' (строка).

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

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

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

Changed in Django 3.1:

Было разрешено использование samesite='None' (строка).

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

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

Changed in Django 2.2.15:

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

HttpResponse.close()

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

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

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

HttpResponse.flush()

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

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

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

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

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

HttpResponse.readable()

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

HttpResponse.seekable()

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

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

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

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

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

Подклассы HttpResponse

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

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

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

url

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

from http import HTTPStatus
from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

Объекты JsonResponse

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

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

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

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

Энкодер, по умолчанию 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.

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

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

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

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

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

Объекты StreamingHttpResponse

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

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

Вопросы производительности

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

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

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

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

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

Атрибуты

StreamingHttpResponse.streaming_content

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

StreamingHttpResponse.status_code

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

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

StreamingHttpResponse.reason_phrase

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

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

StreamingHttpResponse.streaming

Всегда True.

Объекты FileResponse

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

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

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

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

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

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

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

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

Методы

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

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

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