============================ Request and response objects ============================ .. module:: django.http :synopsis: Classes dealing with HTTP requests and responses. Quick overview ============== Django uses request and response objects to pass state through the system. When a page is requested, Django creates an :class:`HttpRequest` object that contains metadata about the request. Then Django loads the appropriate view, passing the :class:`HttpRequest` as the first argument to the view function. Each view is responsible for returning an :class:`HttpResponse` object. This document explains the APIs for :class:`HttpRequest` and :class:`HttpResponse` objects, which are defined in the :mod:`django.http` module. ``HttpRequest`` objects ======================= .. class:: HttpRequest .. _httprequest-attributes: Attributes ---------- All attributes should be considered read-only, unless stated otherwise. .. attribute:: HttpRequest.scheme A string representing the scheme of the request (``http`` or ``https`` usually). .. attribute:: HttpRequest.body The raw HTTP request body as a bytestring. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc. For processing conventional form data, use :attr:`HttpRequest.POST`. You can also read from an ``HttpRequest`` using a file-like interface. See :meth:`HttpRequest.read()`. .. attribute:: HttpRequest.path A string representing the full path to the requested page, not including the scheme or domain. Example: ``"/music/bands/the_beatles/"`` .. attribute:: HttpRequest.path_info Under some Web server configurations, the portion of the URL after the host name is split up into a script prefix portion and a path info portion. The ``path_info`` attribute always contains the path info portion of the path, no matter what Web server is being used. Using this instead of :attr:`~HttpRequest.path` can make your code easier to move between test and deployment servers. For example, if the ``WSGIScriptAlias`` for your application is set to ``"/minfo"``, then ``path`` might be ``"/minfo/music/bands/the_beatles/"`` and ``path_info`` would be ``"/music/bands/the_beatles/"``. .. attribute:: HttpRequest.method A string representing the HTTP method used in the request. This is guaranteed to be uppercase. For example:: if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else() .. attribute:: HttpRequest.encoding A string representing the current encoding used to decode form submission data (or ``None``, which means the :setting:`DEFAULT_CHARSET` setting is used). You can write to this attribute to change the encoding used when accessing the form data. Any subsequent attribute accesses (such as reading from :attr:`GET` or :attr:`POST`) will use the new ``encoding`` value. Useful if you know the form data is not in the :setting:`DEFAULT_CHARSET` encoding. .. attribute:: HttpRequest.content_type A string representing the MIME type of the request, parsed from the ``CONTENT_TYPE`` header. .. attribute:: HttpRequest.content_params A dictionary of key/value parameters included in the ``CONTENT_TYPE`` header. .. attribute:: HttpRequest.GET A dictionary-like object containing all given HTTP GET parameters. See the :class:`QueryDict` documentation below. .. attribute:: HttpRequest.POST A dictionary-like object containing all given HTTP POST parameters, providing that the request contains form data. See the :class:`QueryDict` documentation below. If you need to access raw or non-form data posted in the request, access this through the :attr:`HttpRequest.body` attribute instead. It's possible that a request can come in via POST with an empty ``POST`` dictionary -- if, say, a form is requested via the POST HTTP method but does not include form data. Therefore, you shouldn't use ``if request.POST`` to check for use of the POST method; instead, use ``if request.method == "POST"`` (see :attr:`HttpRequest.method`). ``POST`` does *not* include file-upload information. See :attr:`FILES`. .. attribute:: HttpRequest.COOKIES A dictionary containing all cookies. Keys and values are strings. .. attribute:: HttpRequest.FILES A dictionary-like object containing all uploaded files. Each key in ``FILES`` is the ``name`` from the ````. Each value in ``FILES`` is an :class:`~django.core.files.uploadedfile.UploadedFile`. See :doc:`/topics/files` for more information. ``FILES`` will only contain data if the request method was POST and the ``
`` that posted to the request had ``enctype="multipart/form-data"``. Otherwise, ``FILES`` will be a blank dictionary-like object. .. attribute:: HttpRequest.META A dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples: * ``CONTENT_LENGTH`` -- The length of the request body (as a string). * ``CONTENT_TYPE`` -- The MIME type of the request body. * ``HTTP_ACCEPT`` -- Acceptable content types for the response. * ``HTTP_ACCEPT_ENCODING`` -- Acceptable encodings for the response. * ``HTTP_ACCEPT_LANGUAGE`` -- Acceptable languages for the response. * ``HTTP_HOST`` -- The HTTP Host header sent by the client. * ``HTTP_REFERER`` -- The referring page, if any. * ``HTTP_USER_AGENT`` -- The client's user-agent string. * ``QUERY_STRING`` -- The query string, as a single (unparsed) string. * ``REMOTE_ADDR`` -- The IP address of the client. * ``REMOTE_HOST`` -- The hostname of the client. * ``REMOTE_USER`` -- The user authenticated by the Web server, if any. * ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``. * ``SERVER_NAME`` -- The hostname of the server. * ``SERVER_PORT`` -- The port of the server (as a string). With the exception of ``CONTENT_LENGTH`` and ``CONTENT_TYPE``, as given above, any HTTP headers in the request are converted to ``META`` keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an ``HTTP_`` prefix to the name. So, for example, a header called ``X-Bender`` would be mapped to the ``META`` key ``HTTP_X_BENDER``. Note that :djadmin:`runserver` strips all headers with underscores in the name, so you won't see them in ``META``. This prevents header-spoofing based on ambiguity between underscores and dashes both being normalizing to underscores in WSGI environment variables. It matches the behavior of Web servers like Nginx and Apache 2.4+. :attr:`HttpRequest.headers` is a simpler way to access all HTTP-prefixed headers, plus ``CONTENT_LENGTH`` and ``CONTENT_TYPE``. .. attribute:: HttpRequest.headers A case insensitive, dict-like object that provides access to all HTTP-prefixed headers (plus ``Content-Length`` and ``Content-Type``) from the request. The name of each header is stylized with title-casing (e.g. ``User-Agent``) when it's displayed. You can access headers case-insensitively:: >>> 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) For use in, for example, Django templates, headers can also be looked up using underscores in place of hyphens:: {{ request.headers.user_agent }} .. attribute:: HttpRequest.resolver_match An instance of :class:`~django.urls.ResolverMatch` representing the resolved URL. This attribute is only set after URL resolving took place, which means it's available in all views but not in middleware which are executed before URL resolving takes place (you can use it in :meth:`process_view` though). Attributes set by application code ---------------------------------- Django doesn't set these attributes itself but makes use of them if set by your application. .. attribute:: HttpRequest.current_app The :ttag:`url` template tag will use its value as the ``current_app`` argument to :func:`~django.urls.reverse()`. .. attribute:: HttpRequest.urlconf This will be used as the root URLconf for the current request, overriding the :setting:`ROOT_URLCONF` setting. See :ref:`how-django-processes-a-request` for details. ``urlconf`` can be set to ``None`` to revert any changes made by previous middleware and return to using the :setting:`ROOT_URLCONF`. .. attribute:: HttpRequest.exception_reporter_filter This will be used instead of :setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` for the current request. See :ref:`custom-error-reports` for details. .. attribute:: HttpRequest.exception_reporter_class This will be used instead of :setting:`DEFAULT_EXCEPTION_REPORTER` for the current request. See :ref:`custom-error-reports` for details. Attributes set by middleware ---------------------------- Some of the middleware included in Django's contrib apps set attributes on the request. If you don't see the attribute on a request, be sure the appropriate middleware class is listed in :setting:`MIDDLEWARE`. .. attribute:: HttpRequest.session From the :class:`~django.contrib.sessions.middleware.SessionMiddleware`: A readable and writable, dictionary-like object that represents the current session. .. attribute:: HttpRequest.site From the :class:`~django.contrib.sites.middleware.CurrentSiteMiddleware`: An instance of :class:`~django.contrib.sites.models.Site` or :class:`~django.contrib.sites.requests.RequestSite` as returned by :func:`~django.contrib.sites.shortcuts.get_current_site()` representing the current site. .. attribute:: HttpRequest.user From the :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`: An instance of :setting:`AUTH_USER_MODEL` representing the currently logged-in user. If the user isn't currently logged in, ``user`` will be set to an instance of :class:`~django.contrib.auth.models.AnonymousUser`. You can tell them apart with :attr:`~django.contrib.auth.models.User.is_authenticated`, like so:: if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users. Methods ------- .. method:: HttpRequest.get_host() Returns the originating host of the request using information from the ``HTTP_X_FORWARDED_HOST`` (if :setting:`USE_X_FORWARDED_HOST` is enabled) and ``HTTP_HOST`` headers, in that order. If they don't provide a value, the method uses a combination of ``SERVER_NAME`` and ``SERVER_PORT`` as detailed in :pep:`3333`. Example: ``"127.0.0.1:8000"`` .. note:: The :meth:`~HttpRequest.get_host()` method fails when the host is behind multiple proxies. One solution is to use middleware to rewrite the proxy headers, as in the following example:: 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) This middleware should be positioned before any other middleware that relies on the value of :meth:`~HttpRequest.get_host()` -- for instance, :class:`~django.middleware.common.CommonMiddleware` or :class:`~django.middleware.csrf.CsrfViewMiddleware`. .. method:: HttpRequest.get_port() Returns the originating port of the request using information from the ``HTTP_X_FORWARDED_PORT`` (if :setting:`USE_X_FORWARDED_PORT` is enabled) and ``SERVER_PORT`` ``META`` variables, in that order. .. method:: HttpRequest.get_full_path() Returns the ``path``, plus an appended query string, if applicable. Example: ``"/music/bands/the_beatles/?print=true"`` .. method:: HttpRequest.get_full_path_info() Like :meth:`get_full_path`, but uses :attr:`path_info` instead of :attr:`path`. Example: ``"/minfo/music/bands/the_beatles/?print=true"`` .. method:: HttpRequest.build_absolute_uri(location=None) Returns the absolute URI form of ``location``. If no location is provided, the location will be set to ``request.get_full_path()``. If the location is already an absolute URI, it will not be altered. Otherwise the absolute URI is built using the server variables available in this request. For example: >>> 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/' .. note:: Mixing HTTP and HTTPS on the same site is discouraged, therefore :meth:`~HttpRequest.build_absolute_uri()` will always generate an absolute URI with the same scheme the current request has. If you need to redirect users to HTTPS, it's best to let your Web server redirect all HTTP traffic to HTTPS. .. method:: HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) Returns a cookie value for a signed cookie, or raises a ``django.core.signing.BadSignature`` exception if the signature is no longer valid. If you provide the ``default`` argument the exception will be suppressed and that default value will be returned instead. The optional ``salt`` argument can be used to provide extra protection against brute force attacks on your secret key. If supplied, the ``max_age`` argument will be checked against the signed timestamp attached to the cookie value to ensure the cookie is not older than ``max_age`` seconds. For example:: >>> 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 See :doc:`cryptographic signing ` for more information. .. method:: HttpRequest.is_secure() Returns ``True`` if the request is secure; that is, if it was made with HTTPS. .. method:: HttpRequest.accepts(mime_type) .. versionadded:: 3.1 Returns ``True`` if the request ``Accept`` header matches the ``mime_type`` argument:: >>> request.accepts('text/html') True Most browsers send ``Accept: */*`` by default, so this would return ``True`` for all content types. Setting an explicit ``Accept`` header in API requests can be useful for returning a different content type for those consumers only. See :ref:`content-negotiation-example` of using ``accepts()`` to return different content to API consumers. If a response varies depending on the content of the ``Accept`` header and you are using some form of caching like Django's :mod:`cache middleware `, you should decorate the view with :func:`vary_on_headers('Accept') ` so that the responses are properly cached. .. method:: HttpRequest.is_ajax() .. deprecated:: 3.1 Returns ``True`` if the request was made via an ``XMLHttpRequest``, by checking the ``HTTP_X_REQUESTED_WITH`` header for the string ``'XMLHttpRequest'``. Most modern JavaScript libraries send this header. If you write your own ``XMLHttpRequest`` call (on the browser side), you'll have to set this header manually if you want ``is_ajax()`` to work. If a response varies on whether or not it's requested via AJAX and you are using some form of caching like Django's :mod:`cache middleware `, you should decorate the view with :func:`vary_on_headers('X-Requested-With') ` so that the responses are properly cached. .. method:: HttpRequest.read(size=None) .. method:: HttpRequest.readline() .. method:: HttpRequest.readlines() .. method:: HttpRequest.__iter__() Methods implementing a file-like interface for reading from an ``HttpRequest`` instance. This makes it possible to consume an incoming request in a streaming fashion. A common use-case would be to process a big XML payload with an iterative parser without constructing a whole XML tree in memory. Given this standard interface, an ``HttpRequest`` instance can be passed directly to an XML parser such as :class:`~xml.etree.ElementTree.ElementTree`:: import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element) ``QueryDict`` objects ===================== .. class:: QueryDict In an :class:`HttpRequest` object, the :attr:`~HttpRequest.GET` and :attr:`~HttpRequest.POST` attributes are instances of ``django.http.QueryDict``, a dictionary-like class customized to deal with multiple values for the same key. This is necessary because some HTML form elements, notably ``