#

## Django documentation

# Request and response objects

## Quick overview

Django uses request and response objects to pass state through the system.

When a page is requested, Django creates an `HttpRequest` object that contains metadata about the request. Then Django loads the appropriate view, passing the `HttpRequest` as the first argument to the view function. Each view is responsible for returning an `HttpResponse` object.

This document explains the APIs for `HttpRequest` and `HttpResponse` objects.

## HttpRequest objects

### Attributes

All attributes except `session` should be considered read-only.

`path`

  A string representing the full path to the requested page, not including the domain.

  Example: `"/music/bands/the_beatles/"`

`GET`
  A dictionary-like object containing all given HTTP GET parameters. See the `MultiValueDict` documentation below.
`POST`
  A dictionary-like object containing all given HTTP POST parameters. See the `MultiValueDict` documentation below.
`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.

`COOKIES`
  A standard Python dictionary containing all cookies. Keys and values are strings.
`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 a standard Python dictionary with the following three keys:

  > - `filename` -- The name of the uploaded file, as a Python string.
  > - `content-type` -- The content type of the uploaded file.
  > - `content` -- The raw content of the uploaded file.

  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.

`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`
  > - `CONTENT_TYPE`
  > - `HTTP_ACCEPT_ENCODING`
  > - `HTTP_ACCEPT_LANGUAGE`
  > - `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.
  > - `REQUEST_METHOD` -- A string such as `"GET"` or `"POST"`.
  > - `SERVER_NAME` -- The hostname of the server.
  > - `SERVER_PORT` -- The port of the server.

`user`

  A `django.models.auth.users.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.parts.auth.anonymoususers.AnonymousUser`. You can tell them apart with `is_anonymous()`, like so:

      if request.user.is_anonymous():
          # Do something for anonymous users.
      else:
          # Do something for logged-in users.

`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 session documentation for full details.

`raw_post_data`
  The raw HTTP POST data. This is only useful for advanced processing. Use `POST` instead.

### Methods

`__getitem__(key)`

  Returns the GET/POST value for the given key, checking POST first, then GET. Raises `KeyError` if the key doesn't exist.

  This lets you use dictionary-accessing syntax on an `HttpRequest` instance. Example: `request["foo"]` would return `True` if either `request.POST` or `request.GET` had a `"foo"` key.

`has_key()`
  Returns `True` or `False`, designating whether `request.GET` or `request.POST` has the given key.
`get_full_path()`

  Returns the `path`, plus an appended query string, if applicable.

  Example: `"/music/bands/the_beatles/?print=true"`

### QueryDict objects

In an `HttpRequest` object, the `GET` and `POST` attributes are instances of `django.utils.httpwrappers.QueryDict`. `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>`, 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.

`QueryDict` implements the following standard dictionary methods:

> - `__repr__()`
> - `__getitem__(key)` -- Returns the value for the given key. If the key has more than one value, `__getitem__()` returns the last value.
> - `__setitem__(key, value)` -- Sets the given key to `[value]` (a Python list whose single element is `value`).
> - `__len__()`
> - `get(key, default)` -- Uses the same logic as `__getitem__()` above, with a hook for returning a default value if the key doesn't exist.
> - `has_key(key)`
> - `items()` -- Just like the standard dictionary `items()` method, except this retains the order for values of duplicate keys, if any. For example, if the original query string was `"a=1&b=2&b=3"`, `items()` will return `[("a", ["1"]), ("b", ["2", "3"])]`, where the order of `["2", "3"]` is guaranteed, but the order of `a` vs. `b` isn't.
> - `keys()`
> - `update(other_dict)`

In addition, it has the following methods:

> - `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.
> - `getlist(key)` -- Returns the data with the requested key, as a Python list. Returns an empty list if the key doesn't exist.
> - `setlist(key, list_)` -- Sets the given key to `list_` (unlike `__setitem__()`).
> - `appendlist(key, item)` -- Appends an item to the internal list associated with key.
> - `urlencode()` -- Returns a string of the data in query-string format. Example: `"a=2&b=3&b=5"`.

### Examples

Here's an example HTML form and how Django would treat the input:

    <form action="/foo/bar/" method="post">
    <input type="text" name="your_name" />
    <select multiple="multiple" name="bands">
        <option value="beatles">The Beatles</option>
        <option value="who">The Who</option>
        <option value="zombies">The Zombies</option>
    </select>
    <input type="submit" />
    </form>

If the user enters `"John Smith"` in the `your_name` field and selects both "The Beatles" and "The Zombies" in the multiple select box, here's what Django's request object would have:

    >>> request.GET
    {}
    >>> request.POST
    {'your_name': ['John Smith'], 'bands': ['beatles', 'zombies']}
    >>> request.POST['your_name']
    'John Smith'
    >>> request.POST['bands']
    'zombies'
    >>> request.POST.getlist('bands')
    ['beatles', 'zombies']
    >>> request.POST.get('your_name', 'Adrian')
    'John Smith'
    >>> request.POST.get('nonexistent_field', 'Nowhere Man')
    'Nowhere Man'

### Implementation notes

The `GET`, `POST`, `COOKIES`, `FILES`, `META`, `REQUEST`, `raw_post_data` and `user` attributes are all lazily loaded. That means Django doesn't spend resources calculating the values of those attributes until your code requests them.

## HttpResponse objects

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

The `HttpResponse` class lives at `django.utils.httpwrappers.HttpResponse`.

### Usage

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

    >>> response = HttpResponse("Here's the text of the Web page.")
    >>> response = HttpResponse("Text only, please.", mimetype="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>")

You can add and delete headers using dictionary syntax:

    >>> response = HttpResponse()
    >>> response['X-DJANGO'] = "It's the best."
    >>> del response['X-PHP']
    >>> response['X-DJANGO']
    "It's the best."

Note that `del` doesn't raise `KeyError` if the header doesn't exist.

### Methods

`__init__(content='', mimetype=DEFAULT_MIME_TYPE)`
  Instantiates an `HttpResponse` object with the given page content (a string) and MIME type. The `DEFAULT_MIME_TYPE` is `"text/html"`.
`__setitem__(header, value)`
  Sets the given header name to the given value. Both `header` and `value` should be strings.
`__delitem__(header)`
  Deletes the header with the given name. Fails silently if the header doesn't exist. Case-sensitive.
`__getitem__(header)`
  Returns the value for the given header name. Case-sensitive.
`has_header(header)`
  Returns `True` or `False` based on a case-insensitive check for a header with the given name.
`set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None)`

  Sets a cookie. The parameters are the same as in the 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.
  > - `expires` should be a string in the format `"Wdy, DD-Mon-YY HH:MM:SS GMT"`.
  > - 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.

`delete_cookie(key)`
  Deletes the cookie with the given key. Fails silently if the key doesn't exist.
`get_content_as_string(encoding)`
  Returns the content as a Python string, encoding it from a Unicode object if necessary.
`write(content)`, `flush()` and `tell()`
  These methods make an `HttpResponse` instance a file-like object.

### HttpResponse subclasses

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

`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 URL with no domain (e.g. `"/search/"`).
`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.
`HttpResponseNotFound`
  Acts just like `HttpResponse` but uses a 404 status code.
`HttpResponseForbidden`
  Acts just like `HttpResponse` but uses a 403 status code.
`HttpResponseGone`
  Acts just like `HttpResponse` but uses a 410 status code.
`HttpResponseServerError`
  Acts just like `HttpResponse` but uses a 500 status code.

## Comments

### Richie Hindle October 29, 2005 at 3:58 p.m.

Based on this documentation, I expected this:

response.delete_cookie('my_cookie')

to send a response back to the browser that would delete the cookie. This is not the case - you must have first added the cookie to the response object.

I'd call this a bug - I expected delete_cookie() to send back a cookie-deleting response regardless of the original state of the response object. But if it's not considered a bug, the documentation could be clearer. I interpreted "Fails silently if the key doesn't exist" as "will have no effect if the user's browser doesn't have the given cookie set".

### Bucaro November 13, 2005 at 1:36 p.m.

It is not clear how to implement login and logout actions.

## Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: