Request post or none django что значит
Перейти к содержимому

Request post or none django что значит

  • автор:

Logic behind Form(request.POST or None)

What’s the logic behind request.POST or None ? I haven’t seen such thing in Python projects except Django. Since or operator returns True or False values, how is it possible that if request.POST isn’t None , the Form knows it and takes post as an argument?

form = MyModelForm(request.POST or None) 

In fact, the result should be Form(True) if request.POST isn’t None , otherwise Form(False) . How it works?

asked Jul 7, 2016 at 17:39
18.2k 37 37 gold badges 157 157 silver badges 357 357 bronze badges
Here is a good explanation: stackoverflow.com/a/13870633/771848.
Jul 7, 2016 at 17:42

1 Answer 1

The use of or in this case does not evaluate to True or False , but returns one of the objects.

Keep in mind that or is evaluated from left to right.

When the QueryDict request.POST is empty, it takes a Falsy value, so the item on RHS of the or operation is selected (which is None ), and the form is initialized without vanilla arguments (i.e. with None ):

form = MyModelForm() 

Otherwise, when request.POST is not empty, the form is initialized with the QueryDict:

form = MyModelForm(request.POST) 

Why is it a problem?

Although it is common, a POST request does not per se has content. The or operator evaluates the truthiness of the request.POST operand, and if it is False , it will take the right operand (so None ). This means that even if it is a POST request, it will take None , and thus as result the form is not bounded.

If the form is not bounded, then form.is_valid() will return False , even if an empty QueryDict for request.POST was a valid request.

What can be done to resolve the problem?

We can branch based on the request method, and use request.POST in case of a POST request:

def someview(request): if request.method == 'POST': form = MyForm(request.POST, request.FILES) # … else: form = MyForm() # …

Requests

If you’re doing REST-based web service stuff . you should ignore request.POST.

— Malcom Tredinnick, Django developers group

REST framework’s Request class extends the standard HttpRequest , adding support for REST framework’s flexible request parsing and request authentication.

Request parsing

REST framework’s Request objects provide flexible request parsing that allows you to treat requests with JSON data or other media types in the same way that you would normally deal with form data.

.data

request.data returns the parsed content of the request body. This is similar to the standard request.POST and request.FILES attributes except that:

  • It includes all parsed content, including file and non-file inputs.
  • It supports parsing the content of HTTP methods other than POST , meaning that you can access the content of PUT and PATCH requests.
  • It supports REST framework’s flexible request parsing, rather than just supporting form data. For example you can handle incoming JSON data similarly to how you handle incoming form data.

For more details see the parsers documentation.

.query_params

request.query_params is a more correctly named synonym for request.GET .

For clarity inside your code, we recommend using request.query_params instead of the Django’s standard request.GET . Doing so will help keep your codebase more correct and obvious — any HTTP method type may include query parameters, not just GET requests.

.parsers

The APIView class or @api_view decorator will ensure that this property is automatically set to a list of Parser instances, based on the parser_classes set on the view or based on the DEFAULT_PARSER_CLASSES setting.

You won’t typically need to access this property.

Note: If a client sends malformed content, then accessing request.data may raise a ParseError . By default REST framework’s APIView class or @api_view decorator will catch the error and return a 400 Bad Request response.

If a client sends a request with a content-type that cannot be parsed then a UnsupportedMediaType exception will be raised, which by default will be caught and return a 415 Unsupported Media Type response.

Content negotiation

The request exposes some properties that allow you to determine the result of the content negotiation stage. This allows you to implement behaviour such as selecting a different serialization schemes for different media types.

.accepted_renderer

The renderer instance that was selected by the content negotiation stage.

.accepted_media_type

A string representing the media type that was accepted by the content negotiation stage.

Authentication

REST framework provides flexible, per-request authentication, that gives you the ability to:

  • Use different authentication policies for different parts of your API.
  • Support the use of multiple authentication policies.
  • Provide both user and token information associated with the incoming request.

.user

request.user typically returns an instance of django.contrib.auth.models.User , although the behavior depends on the authentication policy being used.

If the request is unauthenticated the default value of request.user is an instance of django.contrib.auth.models.AnonymousUser .

.auth

request.auth returns any additional authentication context. The exact behavior of request.auth depends on the authentication policy being used, but it may typically be an instance of the token that the request was authenticated against.

If the request is unauthenticated, or if no additional context is present, the default value of request.auth is None .

.authenticators

The APIView class or @api_view decorator will ensure that this property is automatically set to a list of Authentication instances, based on the authentication_classes set on the view or based on the DEFAULT_AUTHENTICATORS setting.

You won’t typically need to access this property.

Note: You may see a WrappedAttributeError raised when calling the .user or .auth properties. These errors originate from an authenticator as a standard AttributeError , however it’s necessary that they be re-raised as a different exception type in order to prevent them from being suppressed by the outer property access. Python will not recognize that the AttributeError originates from the authenticator and will instead assume that the request object does not have a .user or .auth property. The authenticator will need to be fixed.

Browser enhancements

REST framework supports a few browser enhancements such as browser-based PUT , PATCH and DELETE forms.

.method

request.method returns the uppercased string representation of the request’s HTTP method.

Browser-based PUT , PATCH and DELETE forms are transparently supported.

.content_type

request.content_type , returns a string object representing the media type of the HTTP request’s body, or an empty string if no media type was provided.

You won’t typically need to directly access the request’s content type, as you’ll normally rely on REST framework’s default request parsing behavior.

If you do need to access the content type of the request you should use the .content_type property in preference to using request.META.get(‘HTTP_CONTENT_TYPE’) , as it provides transparent support for browser-based non-form content.

.stream

request.stream returns a stream representing the content of the request body.

You won’t typically need to directly access the request’s content, as you’ll normally rely on REST framework’s default request parsing behavior.

Standard HttpRequest attributes

As REST framework’s Request extends Django’s HttpRequest , all the other standard attributes and methods are also available. For example the request.META and request.session dictionaries are available as normal.

Note that due to implementation reasons the Request class does not inherit from HttpRequest class, but instead extends the class using composition.

Documentation built with MkDocs.

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

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

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

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

Объекты HttpRequest ¶

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

Атрибуты¶

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

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

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

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

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

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

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

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

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

HttpRequest. encoding ¶

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

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

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

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

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

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

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

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

Словарный объект, содержащий все загруженные файлы. Каждый ключ в FILES — это name из . Каждое значение в FILES — это UploadedFile .

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

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

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

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

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

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

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

 request.headers.user_agent >> 

HttpRequest. resolver_match ¶

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

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

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

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

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

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

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

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

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

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

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

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

Из 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.

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

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

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

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

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

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

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

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

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.

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

Возвращает значение 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 

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

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

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

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

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

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

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

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *