============================
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.

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.body

    .. versionchanged:: 1.4

    Before Django 1.4, ``HttpRequest.body`` was named
    ``HttpRequest.raw_post_data``.

    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``.

    .. versionadded:: 1.3

    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 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 much 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. See the
    :class:`QueryDict` documentation below.

    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.REQUEST

    For convenience, a dictionary-like object that searches ``POST`` first,
    then ``GET``. Inspired by PHP's ``$_REQUEST``.

    For example, if ``GET = {"name": "john"}`` and ``POST = {"age": '34'}``,
    ``REQUEST["name"]`` would be ``"john"``, and ``REQUEST["age"]`` would be
    ``"34"``.

    It's strongly suggested that you use ``GET`` and ``POST`` instead of
    ``REQUEST``, because the former are more explicit.

.. 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 ``<input type="file" name="" />``. Each
    value in ``FILES`` is an :class:`UploadedFile` as described below.

    See :doc:`/topics/files` for more information.

    Note that ``FILES`` will only contain data if the request method was POST
    and the ``<form>`` 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_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``.

.. attribute:: HttpRequest.user

    A ``django.contrib.auth.models.User`` object representing the currently
    logged-in user. If the user isn't currently logged in, ``user`` will be set
    to an instance of ``django.contrib.auth.models.AnonymousUser``. You
    can tell them apart with ``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
    ``AuthenticationMiddleware`` activated. For more, see
    :doc:`/topics/auth`.

.. 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
    </topics/http/sessions>` 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.

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"``

.. method:: HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

   .. versionadded:: 1.4

   Returns a cookie value for a signed cookie, or raises a
   :class:`~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 </topics/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.

.. method:: HttpRequest.read(size=None)
.. method:: HttpRequest.readline()
.. method:: HttpRequest.readlines()
.. method:: HttpRequest.xreadlines()
.. method:: HttpRequest.__iter__()

    .. versionadded:: 1.3

    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 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)


UploadedFile objects
====================

.. class:: UploadedFile


Attributes
----------

.. attribute::  UploadedFile.name

    The name of the uploaded file.

.. attribute:: UploadedFile.size

    The size, in bytes, of the uploaded file.

Methods
----------

.. method:: UploadedFile.chunks(chunk_size=None)

    Returns a generator that yields sequential chunks of data.

.. method:: UploadedFile.read(num_bytes=None)

    Read a number of bytes from the file.



QueryDict objects
=================

.. class:: QueryDict

In an :class:`HttpRequest` object, the ``GET`` and ``POST`` attributes are instances
of ``django.http.QueryDict``. :class:`QueryDict` is a dictionary-like
class customized to deal with multiple values for the same key. This is
necessary because some HTML form elements, notably
``<select multiple="multiple">``, pass multiple values for the same key.

``QueryDict`` instances are immutable, unless you create a ``copy()`` of them.
That means you can't change attributes of ``request.POST`` and ``request.GET``
directly.

Methods
-------

:class:`QueryDict` implements all the standard dictionary methods, because it's
a subclass of dictionary. Exceptions are outlined here:

.. method:: QueryDict.__getitem__(key)

    Returns the value for the given key. If the key has more than one value,
    ``__getitem__()`` returns the last value. Raises
    ``django.utils.datastructures.MultiValueDictKeyError`` if the key does not
    exist. (This is a subclass of Python's standard ``KeyError``, so you can
    stick to catching ``KeyError``.)

.. method:: QueryDict.__setitem__(key, value)

    Sets the given key to ``[value]`` (a Python list whose single element is
    ``value``). Note that this, as other dictionary functions that have side
    effects, can only be called on a mutable ``QueryDict`` (one that was created
    via ``copy()``).

.. method:: QueryDict.__contains__(key)

    Returns ``True`` if the given key is set. This lets you do, e.g., ``if "foo"
    in request.GET``.

.. method:: QueryDict.get(key, default)

    Uses the same logic as ``__getitem__()`` above, with a hook for returning a
    default value if the key doesn't exist.

.. method:: QueryDict.setdefault(key, default)

    Just like the standard dictionary ``setdefault()`` method, except it uses
    ``__setitem__()`` internally.

.. method:: QueryDict.update(other_dict)

    Takes either a ``QueryDict`` or standard dictionary. Just like the standard
    dictionary ``update()`` method, except it *appends* to the current
    dictionary items rather than replacing them. For example::

          >>> q = QueryDict('a=1')
          >>> q = q.copy() # to make it mutable
          >>> q.update({'a': '2'})
          >>> q.getlist('a')
          [u'1', u'2']
          >>> q['a'] # returns the last
          [u'2']

.. method:: QueryDict.items()

    Just like the standard dictionary ``items()`` method, except this uses the
    same last-value logic as ``__getitem__()``. For example::

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

.. method:: QueryDict.iteritems()

    Just like the standard dictionary ``iteritems()`` method. Like
    :meth:`QueryDict.items()` this uses the same last-value logic as
    :meth:`QueryDict.__getitem__()`.

.. method:: QueryDict.iterlists()

    Like :meth:`QueryDict.iteritems()` except it includes all values, as a list,
    for each member of the dictionary.

.. method:: QueryDict.values()

    Just like the standard dictionary ``values()`` method, except this uses the
    same last-value logic as ``__getitem__()``. For example::

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

.. method:: QueryDict.itervalues()

    Just like :meth:`QueryDict.values()`, except an iterator.

In addition, ``QueryDict`` has the following methods:

.. method:: QueryDict.copy()

    Returns a copy of the object, using ``copy.deepcopy()`` from the Python
    standard library. The copy will be mutable -- that is, you can change its
    values.

.. method:: QueryDict.getlist(key, default)

    Returns the data with the requested key, as a Python list. Returns an
    empty list if the key doesn't exist and no default value was provided.
    It's guaranteed to return a list of some sort unless the default value
    was no list.

    .. versionchanged:: 1.4
        The ``default`` parameter was added.

.. method:: QueryDict.setlist(key, list_)

    Sets the given key to ``list_`` (unlike ``__setitem__()``).

.. method:: QueryDict.appendlist(key, item)

    Appends an item to the internal list associated with key.

.. method:: QueryDict.setlistdefault(key, default_list)

    Just like ``setdefault``, except it takes a list of values instead of a
    single value.

.. method:: QueryDict.lists()

    Like :meth:`items()`, except it includes all values, as a list, for each
    member of the dictionary. For example::

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

.. method:: QueryDict.dict()

    .. versionadded:: 1.4

    Returns ``dict`` representation of ``QueryDict``. For every (key, list)
    pair in ``QueryDict``, ``dict`` will have (key, item), where item is one
    element of the list, using same logic as :meth:`QueryDict.__getitem__()`::

        >>> q = QueryDict('a=1&a=3&a=5')
        >>> q.dict()
        {u'a': u'5'}

.. method:: QueryDict.urlencode([safe])

    Returns a string of the data in query-string format. Example::

        >>> q = QueryDict('a=2&b=3&b=5')
        >>> q.urlencode()
        'a=2&b=3&b=5'

    .. versionchanged:: 1.3
       The ``safe`` parameter was added.

    Optionally, urlencode can be passed characters which
    do not require encoding. For example::

        >>> q = QueryDict('', mutable=True)
        >>> q['next'] = '/a&b/'
        >>> q.urlencode(safe='/')
        'next=/a%26b/'

HttpResponse objects
====================

.. class:: HttpResponse

In contrast to :class:`HttpRequest` objects, which are created automatically by
Django, :class:`HttpResponse` objects are your responsibility. Each view you
write is responsible for instantiating, populating and returning an
:class:`HttpResponse`.

The :class:`HttpResponse` class lives in the :mod:`django.http` module.

Usage
-----

Passing strings
~~~~~~~~~~~~~~~

Typical usage is to pass the contents of the page, as a string, to the
:class:`HttpResponse` constructor::

    >>> from django.http import HttpResponse
    >>> response = HttpResponse("Here's the text of the Web page.")
    >>> response = HttpResponse("Text only, please.", content_type="text/plain")

But if you want to add content incrementally, you can use ``response`` as a
file-like object::

    >>> response = HttpResponse()
    >>> response.write("<p>Here's the text of the Web page.</p>")
    >>> response.write("<p>Here's another paragraph.</p>")

Passing iterators
~~~~~~~~~~~~~~~~~

Finally, you can pass ``HttpResponse`` an iterator rather than passing it
hard-coded strings. If you use this technique, follow these guidelines:

* The iterator should return strings.
* If an :class:`HttpResponse` has been initialized with an iterator as its
  content, you can't use the :class:`HttpResponse` instance as a file-like
  object. Doing so will raise ``Exception``.

Setting headers
~~~~~~~~~~~~~~~

To set or remove a header in your response, treat it like a dictionary::

    >>> response = HttpResponse()
    >>> response['Cache-Control'] = 'no-cache'
    >>> del response['Cache-Control']

Note that unlike a dictionary, ``del`` doesn't raise ``KeyError`` if the header
doesn't exist.

HTTP headers cannot contain newlines. An attempt to set a header containing a
newline character (CR or LF) will raise ``BadHeaderError``

Telling the browser to treat the response as a file attachment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To tell the browser to treat the response as a file attachment, use the
``content_type`` argument and set the ``Content-Disposition`` header. For example,
this is how you might return a Microsoft Excel spreadsheet::

    >>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
    >>> response['Content-Disposition'] = 'attachment; filename=foo.xls'

There's nothing Django-specific about the ``Content-Disposition`` header, but
it's easy to forget the syntax, so we've included it here.

Attributes
----------

.. attribute:: HttpResponse.content

    A string representing the content, encoded from a Unicode
    object if necessary.

.. attribute:: HttpResponse.status_code

    The `HTTP Status code`_ for the response.

Methods
-------

.. method:: HttpResponse.__init__(content='', content_type=None, status=200)

    Instantiates an ``HttpResponse`` object with the given page content and
    content type.

    ``content`` should be an iterator or a string. If it's an
    iterator, it should return strings, and those strings will be
    joined together to form the content of the response. If it is not
    an iterator or a string, it will be converted to a string when
    accessed.

    ``content_type`` is the MIME type optionally completed by a character set
    encoding and is used to fill the HTTP ``Content-Type`` header. If not
    specified, it is formed by the :setting:`DEFAULT_CONTENT_TYPE` and
    :setting:`DEFAULT_CHARSET` settings, by default: "`text/html; charset=utf-8`".

    Historically, this parameter was called ``mimetype`` (now deprecated).

    ``status`` is the `HTTP Status code`_ for the response.


.. method:: HttpResponse.__setitem__(header, value)

    Sets the given header name to the given value. Both ``header`` and
    ``value`` should be strings.

.. method:: HttpResponse.__delitem__(header)

    Deletes the header with the given name. Fails silently if the header
    doesn't exist. Case-insensitive.

.. method:: HttpResponse.__getitem__(header)

    Returns the value for the given header name. Case-insensitive.

.. method:: HttpResponse.has_header(header)

    Returns ``True`` or ``False`` based on a case-insensitive check for a
    header with the given name.

.. method:: HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)

    .. versionchanged:: 1.3

    The possibility of specifying a ``datetime.datetime`` object in
    ``expires``, and the auto-calculation of ``max_age`` in such case
    was added. The ``httponly`` argument was also added.

    .. versionchanged:: 1.4

    The default value for httponly was changed from ``False`` to ``True``.

    Sets a cookie. The parameters are the same as in the :class:`Cookie.Morsel`
    object in the Python standard library.

    * ``max_age`` should be a number of seconds, or ``None`` (default) if
      the cookie should last only as long as the client's browser session.
      If ``expires`` is not specified, it will be calculated.
    * ``expires`` should either be a string in the format
      ``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
      in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
      will be calculated.
    * Use ``domain`` if you want to set a cross-domain cookie. For example,
      ``domain=".lawrence.com"`` will set a cookie that is readable by
      the domains www.lawrence.com, blogs.lawrence.com and
      calendars.lawrence.com. Otherwise, a cookie will only be readable by
      the domain that set it.
    * Use ``httponly=True`` if you want to prevent client-side
      JavaScript from having access to the cookie.

      HTTPOnly_ is a flag included in a Set-Cookie HTTP response
      header. It is not part of the :rfc:`2109` standard for cookies,
      and it isn't honored consistently by all browsers. However,
      when it is honored, it can be a useful way to mitigate the
      risk of client side script accessing the protected cookie
      data.

    .. _HTTPOnly: https://www.owasp.org/index.php/HTTPOnly

.. method:: HttpResponse.set_signed_cookie(key, value='', salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)

    .. versionadded:: 1.4

    Like :meth:`~HttpResponse.set_cookie()`, but
    :doc:`cryptographic signing </topics/signing>` the cookie before setting
    it. Use in conjunction with :meth:`HttpRequest.get_signed_cookie`.
    You can use the optional ``salt`` argument for added key strength, but
    you will need to remember to pass it to the corresponding
    :meth:`HttpRequest.get_signed_cookie` call.

.. method:: HttpResponse.delete_cookie(key, path='/', domain=None)

    Deletes the cookie with the given key. Fails silently if the key doesn't
    exist.

    Due to the way cookies work, ``path`` and ``domain`` should be the same
    values you used in ``set_cookie()`` -- otherwise the cookie may not be
    deleted.

.. method:: HttpResponse.write(content)

    This method makes an :class:`HttpResponse` instance a file-like object.

.. method:: HttpResponse.flush()

    This method makes an :class:`HttpResponse` instance a file-like object.

.. method:: HttpResponse.tell()

    This method makes an :class:`HttpResponse` instance a file-like object.

.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10


.. _ref-httpresponse-subclasses:

HttpResponse subclasses
-----------------------

Django includes a number of ``HttpResponse`` subclasses that handle different
types of HTTP responses. Like ``HttpResponse``, these subclasses live in
:mod:`django.http`.

.. class:: HttpResponseRedirect

    The constructor takes a single argument -- the path to redirect to. This
    can be a fully qualified URL (e.g. ``'http://www.yahoo.com/search/'``) or
    an absolute path with no domain (e.g. ``'/search/'``). Note that this
    returns an HTTP status code 302.

.. class:: HttpResponsePermanentRedirect

    Like :class:`HttpResponseRedirect`, but it returns a permanent redirect
    (HTTP status code 301) instead of a "found" redirect (status code 302).

.. class:: HttpResponseNotModified

    The constructor doesn't take any arguments. Use this to designate that a
    page hasn't been modified since the user's last request (status code 304).

.. class:: HttpResponseBadRequest

    Acts just like :class:`HttpResponse` but uses a 400 status code.

.. class:: HttpResponseNotFound

    Acts just like :class:`HttpResponse` but uses a 404 status code.

.. class:: HttpResponseForbidden

    Acts just like :class:`HttpResponse` but uses a 403 status code.

.. class:: HttpResponseNotAllowed

    Like :class:`HttpResponse`, but uses a 405 status code. Takes a single,
    required argument: a list of permitted methods (e.g. ``['GET', 'POST']``).

.. class:: HttpResponseGone

    Acts just like :class:`HttpResponse` but uses a 410 status code.

.. class:: HttpResponseServerError

    Acts just like :class:`HttpResponse` but uses a 500 status code.

.. note::

    If a custom subclass of :class:`HttpResponse` implements a ``render``
    method, Django will treat it as emulating a
    :class:`~django.template.response.SimpleTemplateResponse`, and the
    ``render`` method must itself return a valid response object.
