============================ 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 below. ``session`` is a notable exception. .. 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 byte string. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc. For processing conventional form data, use ``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. 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 ``GET`` or ``POST``) will use the new ``encoding`` value. Useful if you know the form data is not in the :setting:`DEFAULT_CHARSET` encoding. .. 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 above). Note: ``POST`` does *not* include file-upload information. See ``FILES``. .. attribute:: HttpRequest.COOKIES A standard Python 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. Note that ``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 standard Python 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+. .. attribute:: HttpRequest.user An object of type :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 :meth:`~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. ``user`` is only available if your Django installation has the :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` activated. For more, see :doc:`/topics/auth/index`. .. attribute:: HttpRequest.session A readable-and-writable, dictionary-like object that represents the current session. This is only available if your Django installation has session support activated. See the :doc:`session documentation ` for full details. .. attribute:: HttpRequest.urlconf Not defined by Django itself, but will be read if other code (e.g., a custom middleware class) sets it. When present, 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`. .. versionchanged:: 1.9 Setting ``urlconf=None`` raised :exc:`~django.core.exceptions.ImproperlyConfigured` in older versions. .. attribute:: HttpRequest.resolver_match An instance of :class:`~django.core.urlresolvers.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 methods which are executed before url resolving takes place (like ``process_request``, you can use ``process_view`` instead). .. attribute:: HttpRequest.current_app .. versionadded:: 1.8 Not defined by Django itself, but if set, the :ttag:`url` template tag will use its value as the ``current_app`` argument to :func:`~django.core.urlresolvers.reverse()`. 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(object): FORWARDED_FOR_FIELDS = [ 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST', 'HTTP_X_FORWARDED_SERVER', ] def process_request(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() 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_full_path() Returns the ``path``, plus an appended query string, if applicable. Example: ``"/music/bands/the_beatles/?print=true"`` .. method:: HttpRequest.build_absolute_uri(location) 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. Example: ``"http://example.com/music/bands/the_beatles/?print=true"`` .. 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 webserver 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('non-existing-cookie') ... KeyError: 'non-existing-cookie' >>> request.get_signed_cookie('non-existing-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.is_ajax() 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('HTTP_X_REQUESTED_WITH') ` so that the responses are properly cached. .. method:: HttpRequest.read(size=None) .. method:: HttpRequest.readline() .. method:: HttpRequest.readlines() .. method:: HttpRequest.xreadlines() .. 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 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 ``GET`` and ``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 ``