| 1 |
============================ |
|---|
| 2 |
Request and response objects |
|---|
| 3 |
============================ |
|---|
| 4 |
|
|---|
| 5 |
Quick overview |
|---|
| 6 |
============== |
|---|
| 7 |
|
|---|
| 8 |
Django uses request and response objects to pass state through the system. |
|---|
| 9 |
|
|---|
| 10 |
When a page is requested, Django creates an ``HttpRequest`` object that |
|---|
| 11 |
contains metadata about the request. Then Django loads the appropriate view, |
|---|
| 12 |
passing the ``HttpRequest`` as the first argument to the view function. Each |
|---|
| 13 |
view is responsible for returning an ``HttpResponse`` object. |
|---|
| 14 |
|
|---|
| 15 |
This document explains the APIs for ``HttpRequest`` and ``HttpResponse`` |
|---|
| 16 |
objects. |
|---|
| 17 |
|
|---|
| 18 |
HttpRequest objects |
|---|
| 19 |
=================== |
|---|
| 20 |
|
|---|
| 21 |
Attributes |
|---|
| 22 |
---------- |
|---|
| 23 |
|
|---|
| 24 |
All attributes except ``session`` should be considered read-only. |
|---|
| 25 |
|
|---|
| 26 |
``path`` |
|---|
| 27 |
A string representing the full path to the requested page, not including |
|---|
| 28 |
the domain. |
|---|
| 29 |
|
|---|
| 30 |
Example: ``"/music/bands/the_beatles/"`` |
|---|
| 31 |
|
|---|
| 32 |
``method`` |
|---|
| 33 |
A string representing the HTTP method used in the request. This is |
|---|
| 34 |
guaranteed to be uppercase. Example:: |
|---|
| 35 |
|
|---|
| 36 |
if request.method == 'GET': |
|---|
| 37 |
do_something() |
|---|
| 38 |
elif request.method == 'POST': |
|---|
| 39 |
do_something_else() |
|---|
| 40 |
|
|---|
| 41 |
``encoding`` |
|---|
| 42 |
**New in Django development version** |
|---|
| 43 |
|
|---|
| 44 |
A string representing the current encoding used to decode form submission |
|---|
| 45 |
data (or ``None``, which means the ``DEFAULT_CHARSET`` setting is used). |
|---|
| 46 |
You can write to this attribute to change the encoding used when accessing |
|---|
| 47 |
the form data. Any subsequent attribute accesses (such as reading from |
|---|
| 48 |
``GET`` or ``POST``) will use the new ``encoding`` value. Useful if you |
|---|
| 49 |
know the form data is not in the ``DEFAULT_CHARSET`` encoding. |
|---|
| 50 |
|
|---|
| 51 |
``GET`` |
|---|
| 52 |
A dictionary-like object containing all given HTTP GET parameters. See the |
|---|
| 53 |
``QueryDict`` documentation below. |
|---|
| 54 |
|
|---|
| 55 |
``POST`` |
|---|
| 56 |
A dictionary-like object containing all given HTTP POST parameters. See the |
|---|
| 57 |
``QueryDict`` documentation below. |
|---|
| 58 |
|
|---|
| 59 |
It's possible that a request can come in via POST with an empty ``POST`` |
|---|
| 60 |
dictionary -- if, say, a form is requested via the POST HTTP method but |
|---|
| 61 |
does not include form data. Therefore, you shouldn't use ``if request.POST`` |
|---|
| 62 |
to check for use of the POST method; instead, use ``if request.method == |
|---|
| 63 |
"POST"`` (see above). |
|---|
| 64 |
|
|---|
| 65 |
Note: ``POST`` does *not* include file-upload information. See ``FILES``. |
|---|
| 66 |
|
|---|
| 67 |
``REQUEST`` |
|---|
| 68 |
For convenience, a dictionary-like object that searches ``POST`` first, |
|---|
| 69 |
then ``GET``. Inspired by PHP's ``$_REQUEST``. |
|---|
| 70 |
|
|---|
| 71 |
For example, if ``GET = {"name": "john"}`` and ``POST = {"age": '34'}``, |
|---|
| 72 |
``REQUEST["name"]`` would be ``"john"``, and ``REQUEST["age"]`` would be |
|---|
| 73 |
``"34"``. |
|---|
| 74 |
|
|---|
| 75 |
It's strongly suggested that you use ``GET`` and ``POST`` instead of |
|---|
| 76 |
``REQUEST``, because the former are more explicit. |
|---|
| 77 |
|
|---|
| 78 |
``COOKIES`` |
|---|
| 79 |
A standard Python dictionary containing all cookies. Keys and values are |
|---|
| 80 |
strings. |
|---|
| 81 |
|
|---|
| 82 |
``FILES`` |
|---|
| 83 |
A dictionary-like object containing all uploaded files. Each key in |
|---|
| 84 |
``FILES`` is the ``name`` from the ``<input type="file" name="" />``. Each |
|---|
| 85 |
value in ``FILES`` is a standard Python dictionary with the following three |
|---|
| 86 |
keys: |
|---|
| 87 |
|
|---|
| 88 |
* ``filename`` -- The name of the uploaded file, as a Python string. |
|---|
| 89 |
* ``content-type`` -- The content type of the uploaded file. |
|---|
| 90 |
* ``content`` -- The raw content of the uploaded file. |
|---|
| 91 |
|
|---|
| 92 |
Note that ``FILES`` will only contain data if the request method was POST |
|---|
| 93 |
and the ``<form>`` that posted to the request had |
|---|
| 94 |
``enctype="multipart/form-data"``. Otherwise, ``FILES`` will be a blank |
|---|
| 95 |
dictionary-like object. |
|---|
| 96 |
|
|---|
| 97 |
``META`` |
|---|
| 98 |
A standard Python dictionary containing all available HTTP headers. |
|---|
| 99 |
Available headers depend on the client and server, but here are some |
|---|
| 100 |
examples: |
|---|
| 101 |
|
|---|
| 102 |
* ``CONTENT_LENGTH`` |
|---|
| 103 |
* ``CONTENT_TYPE`` |
|---|
| 104 |
* ``HTTP_ACCEPT_ENCODING`` |
|---|
| 105 |
* ``HTTP_ACCEPT_LANGUAGE`` |
|---|
| 106 |
* ``HTTP_HOST`` -- The HTTP Host header sent by the client. |
|---|
| 107 |
* ``HTTP_REFERER`` -- The referring page, if any. |
|---|
| 108 |
* ``HTTP_USER_AGENT`` -- The client's user-agent string. |
|---|
| 109 |
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string. |
|---|
| 110 |
* ``REMOTE_ADDR`` -- The IP address of the client. |
|---|
| 111 |
* ``REMOTE_HOST`` -- The hostname of the client. |
|---|
| 112 |
* ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``. |
|---|
| 113 |
* ``SERVER_NAME`` -- The hostname of the server. |
|---|
| 114 |
* ``SERVER_PORT`` -- The port of the server. |
|---|
| 115 |
|
|---|
| 116 |
``user`` |
|---|
| 117 |
A ``django.contrib.auth.models.User`` object representing the currently |
|---|
| 118 |
logged-in user. If the user isn't currently logged in, ``user`` will be set |
|---|
| 119 |
to an instance of ``django.contrib.auth.models.AnonymousUser``. You |
|---|
| 120 |
can tell them apart with ``is_authenticated()``, like so:: |
|---|
| 121 |
|
|---|
| 122 |
if request.user.is_authenticated(): |
|---|
| 123 |
# Do something for logged-in users. |
|---|
| 124 |
else: |
|---|
| 125 |
# Do something for anonymous users. |
|---|
| 126 |
|
|---|
| 127 |
``user`` is only available if your Django installation has the |
|---|
| 128 |
``AuthenticationMiddleware`` activated. For more, see |
|---|
| 129 |
`Authentication in Web requests`_. |
|---|
| 130 |
|
|---|
| 131 |
.. _Authentication in Web requests: ../authentication/#authentication-in-web-requests |
|---|
| 132 |
|
|---|
| 133 |
``session`` |
|---|
| 134 |
A readable-and-writable, dictionary-like object that represents the current |
|---|
| 135 |
session. This is only available if your Django installation has session |
|---|
| 136 |
support activated. See the `session documentation`_ for full details. |
|---|
| 137 |
|
|---|
| 138 |
.. _`session documentation`: ../sessions/ |
|---|
| 139 |
|
|---|
| 140 |
``raw_post_data`` |
|---|
| 141 |
The raw HTTP POST data. This is only useful for advanced processing. Use |
|---|
| 142 |
``POST`` instead. |
|---|
| 143 |
|
|---|
| 144 |
``urlconf`` |
|---|
| 145 |
Not defined by Django itself, but will be read if other code |
|---|
| 146 |
(e.g., a custom middleware class) sets it. When present, this will |
|---|
| 147 |
be used as the root URLconf for the current request, overriding |
|---|
| 148 |
the ``ROOT_URLCONF`` setting. See `How Django processes a |
|---|
| 149 |
request`_ for details. |
|---|
| 150 |
|
|---|
| 151 |
.. _How Django processes a request: ../url_dispatch/#how-django-processes-a-request |
|---|
| 152 |
|
|---|
| 153 |
Methods |
|---|
| 154 |
------- |
|---|
| 155 |
|
|---|
| 156 |
``__getitem__(key)`` |
|---|
| 157 |
Returns the GET/POST value for the given key, checking POST first, then |
|---|
| 158 |
GET. Raises ``KeyError`` if the key doesn't exist. |
|---|
| 159 |
|
|---|
| 160 |
This lets you use dictionary-accessing syntax on an ``HttpRequest`` |
|---|
| 161 |
instance. Example: ``request["foo"]`` would return ``True`` if either |
|---|
| 162 |
``request.POST`` or ``request.GET`` had a ``"foo"`` key. |
|---|
| 163 |
|
|---|
| 164 |
``has_key()`` |
|---|
| 165 |
Returns ``True`` or ``False``, designating whether ``request.GET`` or |
|---|
| 166 |
``request.POST`` has the given key. |
|---|
| 167 |
|
|---|
| 168 |
``get_host()`` |
|---|
| 169 |
**New in Django development version** |
|---|
| 170 |
|
|---|
| 171 |
Returns the originating host of the request using information from the |
|---|
| 172 |
``HTTP_X_FORWARDED_HOST`` and ``HTTP_HOST`` headers (in that order). If |
|---|
| 173 |
they don't provide a value, the method uses a combination of |
|---|
| 174 |
``SERVER_NAME`` and ``SERVER_PORT`` as detailed in `PEP 333`_. |
|---|
| 175 |
|
|---|
| 176 |
.. _PEP 333: http://www.python.org/dev/peps/pep-0333/ |
|---|
| 177 |
|
|---|
| 178 |
Example: ``"127.0.0.1:8000"`` |
|---|
| 179 |
|
|---|
| 180 |
``get_full_path()`` |
|---|
| 181 |
Returns the ``path``, plus an appended query string, if applicable. |
|---|
| 182 |
|
|---|
| 183 |
Example: ``"/music/bands/the_beatles/?print=true"`` |
|---|
| 184 |
|
|---|
| 185 |
``build_absolute_uri(location)`` |
|---|
| 186 |
**New in Django development version** |
|---|
| 187 |
|
|---|
| 188 |
Returns the absolute URI form of ``location``. If no location is provided, |
|---|
| 189 |
the location will be set to ``request.get_full_path()``. |
|---|
| 190 |
|
|---|
| 191 |
If the location is already an absolute URI, it will not be altered. |
|---|
| 192 |
Otherwise the absolute URI is built using the server variables available in |
|---|
| 193 |
this request. |
|---|
| 194 |
|
|---|
| 195 |
Example: ``"http://example.com/music/bands/the_beatles/?print=true"`` |
|---|
| 196 |
|
|---|
| 197 |
``is_secure()`` |
|---|
| 198 |
Returns ``True`` if the request is secure; that is, if it was made with |
|---|
| 199 |
HTTPS. |
|---|
| 200 |
|
|---|
| 201 |
``is_ajax()`` |
|---|
| 202 |
**New in Django development version** |
|---|
| 203 |
|
|---|
| 204 |
Returns ``True`` if the request was made via an ``XMLHttpRequest``, by checking |
|---|
| 205 |
the ``HTTP_X_REQUESTED_WITH`` header for the string ``'XMLHttpRequest'``. The |
|---|
| 206 |
following major JavaScript libraries all send this header: |
|---|
| 207 |
|
|---|
| 208 |
* jQuery |
|---|
| 209 |
* Dojo |
|---|
| 210 |
* MochiKit |
|---|
| 211 |
* MooTools |
|---|
| 212 |
* Prototype |
|---|
| 213 |
* YUI |
|---|
| 214 |
|
|---|
| 215 |
If you write your own XMLHttpRequest call (on the browser side), you'll |
|---|
| 216 |
have to set this header manually if you want ``is_ajax()`` to work. |
|---|
| 217 |
|
|---|
| 218 |
QueryDict objects |
|---|
| 219 |
----------------- |
|---|
| 220 |
|
|---|
| 221 |
In an ``HttpRequest`` object, the ``GET`` and ``POST`` attributes are instances |
|---|
| 222 |
of ``django.http.QueryDict``. ``QueryDict`` is a dictionary-like |
|---|
| 223 |
class customized to deal with multiple values for the same key. This is |
|---|
| 224 |
necessary because some HTML form elements, notably |
|---|
| 225 |
``<select multiple="multiple">``, pass multiple values for the same key. |
|---|
| 226 |
|
|---|
| 227 |
``QueryDict`` instances are immutable, unless you create a ``copy()`` of them. |
|---|
| 228 |
That means you can't change attributes of ``request.POST`` and ``request.GET`` |
|---|
| 229 |
directly. |
|---|
| 230 |
|
|---|
| 231 |
``QueryDict`` implements all the standard dictionary methods, because it's a |
|---|
| 232 |
subclass of dictionary. Exceptions are outlined here: |
|---|
| 233 |
|
|---|
| 234 |
* ``__getitem__(key)`` -- Returns the value for the given key. If the key |
|---|
| 235 |
has more than one value, ``__getitem__()`` returns the last value. |
|---|
| 236 |
Raises ``django.utils.datastructure.MultiValueDictKeyError`` if the key |
|---|
| 237 |
does not exist. (This is a subclass of Python's standard ``KeyError``, |
|---|
| 238 |
so you can stick to catching ``KeyError``.) |
|---|
| 239 |
|
|---|
| 240 |
* ``__setitem__(key, value)`` -- Sets the given key to ``[value]`` |
|---|
| 241 |
(a Python list whose single element is ``value``). Note that this, as |
|---|
| 242 |
other dictionary functions that have side effects, can only be called on |
|---|
| 243 |
a mutable ``QueryDict`` (one that was created via ``copy()``). |
|---|
| 244 |
|
|---|
| 245 |
* ``__contains__(key)`` -- Returns ``True`` if the given key is set. This |
|---|
| 246 |
lets you do, e.g., ``if "foo" in request.GET``. |
|---|
| 247 |
|
|---|
| 248 |
* ``get(key, default)`` -- Uses the same logic as ``__getitem__()`` above, |
|---|
| 249 |
with a hook for returning a default value if the key doesn't exist. |
|---|
| 250 |
|
|---|
| 251 |
* ``has_key(key)`` |
|---|
| 252 |
|
|---|
| 253 |
* ``setdefault(key, default)`` -- Just like the standard dictionary |
|---|
| 254 |
``setdefault()`` method, except it uses ``__setitem__`` internally. |
|---|
| 255 |
|
|---|
| 256 |
* ``update(other_dict)`` -- Takes either a ``QueryDict`` or standard |
|---|
| 257 |
dictionary. Just like the standard dictionary ``update()`` method, except |
|---|
| 258 |
it *appends* to the current dictionary items rather than replacing them. |
|---|
| 259 |
For example:: |
|---|
| 260 |
|
|---|
| 261 |
>>> q = QueryDict('a=1') |
|---|
| 262 |
>>> q = q.copy() # to make it mutable |
|---|
| 263 |
>>> q.update({'a': '2'}) |
|---|
| 264 |
>>> q.getlist('a') |
|---|
| 265 |
['1', '2'] |
|---|
| 266 |
>>> q['a'] # returns the last |
|---|
| 267 |
['2'] |
|---|
| 268 |
|
|---|
| 269 |
* ``items()`` -- Just like the standard dictionary ``items()`` method, |
|---|
| 270 |
except this uses the same last-value logic as ``__getitem()__``. For |
|---|
| 271 |
example:: |
|---|
| 272 |
|
|---|
| 273 |
>>> q = QueryDict('a=1&a=2&a=3') |
|---|
| 274 |
>>> q.items() |
|---|
| 275 |
[('a', '3')] |
|---|
| 276 |
|
|---|
| 277 |
* ``values()`` -- Just like the standard dictionary ``values()`` method, |
|---|
| 278 |
except this uses the same last-value logic as ``__getitem()__``. For |
|---|
| 279 |
example:: |
|---|
| 280 |
|
|---|
| 281 |
>>> q = QueryDict('a=1&a=2&a=3') |
|---|
| 282 |
>>> q.values() |
|---|
| 283 |
['3'] |
|---|
| 284 |
|
|---|
| 285 |
In addition, ``QueryDict`` has the following methods: |
|---|
| 286 |
|
|---|
| 287 |
* ``copy()`` -- Returns a copy of the object, using ``copy.deepcopy()`` |
|---|
| 288 |
from the Python standard library. The copy will be mutable -- that is, |
|---|
| 289 |
you can change its values. |
|---|
| 290 |
|
|---|
| 291 |
* ``getlist(key)`` -- Returns the data with the requested key, as a Python |
|---|
| 292 |
list. Returns an empty list if the key doesn't exist. It's guaranteed to |
|---|
| 293 |
return a list of some sort. |
|---|
| 294 |
|
|---|
| 295 |
* ``setlist(key, list_)`` -- Sets the given key to ``list_`` (unlike |
|---|
| 296 |
``__setitem__()``). |
|---|
| 297 |
|
|---|
| 298 |
* ``appendlist(key, item)`` -- Appends an item to the internal list |
|---|
| 299 |
associated with key. |
|---|
| 300 |
|
|---|
| 301 |
* ``setlistdefault(key, default_list)`` -- Just like ``setdefault``, except |
|---|
| 302 |
it takes a list of values instead of a single value. |
|---|
| 303 |
|
|---|
| 304 |
* ``lists()`` -- Like ``items()``, except it includes all values, as a list, |
|---|
| 305 |
for each member of the dictionary. For example:: |
|---|
| 306 |
|
|---|
| 307 |
>>> q = QueryDict('a=1&a=2&a=3') |
|---|
| 308 |
>>> q.lists() |
|---|
| 309 |
[('a', ['1', '2', '3'])] |
|---|
| 310 |
|
|---|
| 311 |
* ``urlencode()`` -- Returns a string of the data in query-string format. |
|---|
| 312 |
Example: ``"a=2&b=3&b=5"``. |
|---|
| 313 |
|
|---|
| 314 |
Examples |
|---|
| 315 |
-------- |
|---|
| 316 |
|
|---|
| 317 |
Here's an example HTML form and how Django would treat the input:: |
|---|
| 318 |
|
|---|
| 319 |
<form action="/foo/bar/" method="post"> |
|---|
| 320 |
<input type="text" name="your_name" /> |
|---|
| 321 |
<select multiple="multiple" name="bands"> |
|---|
| 322 |
<option value="beatles">The Beatles</option> |
|---|
| 323 |
<option value="who">The Who</option> |
|---|
| 324 |
<option value="zombies">The Zombies</option> |
|---|
| 325 |
</select> |
|---|
| 326 |
<input type="submit" /> |
|---|
| 327 |
</form> |
|---|
| 328 |
|
|---|
| 329 |
If the user enters ``"John Smith"`` in the ``your_name`` field and selects both |
|---|
| 330 |
"The Beatles" and "The Zombies" in the multiple select box, here's what |
|---|
| 331 |
Django's request object would have:: |
|---|
| 332 |
|
|---|
| 333 |
>>> request.GET |
|---|
| 334 |
{} |
|---|
| 335 |
>>> request.POST |
|---|
| 336 |
{'your_name': ['John Smith'], 'bands': ['beatles', 'zombies']} |
|---|
| 337 |
>>> request.POST['your_name'] |
|---|
| 338 |
'John Smith' |
|---|
| 339 |
>>> request.POST['bands'] |
|---|
| 340 |
'zombies' |
|---|
| 341 |
>>> request.POST.getlist('bands') |
|---|
| 342 |
['beatles', 'zombies'] |
|---|
| 343 |
>>> request.POST.get('your_name', 'Adrian') |
|---|
| 344 |
'John Smith' |
|---|
| 345 |
>>> request.POST.get('nonexistent_field', 'Nowhere Man') |
|---|
| 346 |
'Nowhere Man' |
|---|
| 347 |
|
|---|
| 348 |
Implementation notes |
|---|
| 349 |
-------------------- |
|---|
| 350 |
|
|---|
| 351 |
The ``GET``, ``POST``, ``COOKIES``, ``FILES``, ``META``, ``REQUEST``, |
|---|
| 352 |
``raw_post_data`` and ``user`` attributes are all lazily loaded. That means |
|---|
| 353 |
Django doesn't spend resources calculating the values of those attributes until |
|---|
| 354 |
your code requests them. |
|---|
| 355 |
|
|---|
| 356 |
HttpResponse objects |
|---|
| 357 |
==================== |
|---|
| 358 |
|
|---|
| 359 |
In contrast to ``HttpRequest`` objects, which are created automatically by |
|---|
| 360 |
Django, ``HttpResponse`` objects are your responsibility. Each view you write |
|---|
| 361 |
is responsible for instantiating, populating and returning an ``HttpResponse``. |
|---|
| 362 |
|
|---|
| 363 |
The ``HttpResponse`` class lives in the ``django.http`` module. |
|---|
| 364 |
|
|---|
| 365 |
Usage |
|---|
| 366 |
----- |
|---|
| 367 |
|
|---|
| 368 |
Passing strings |
|---|
| 369 |
~~~~~~~~~~~~~~~ |
|---|
| 370 |
|
|---|
| 371 |
Typical usage is to pass the contents of the page, as a string, to the |
|---|
| 372 |
``HttpResponse`` constructor:: |
|---|
| 373 |
|
|---|
| 374 |
>>> response = HttpResponse("Here's the text of the Web page.") |
|---|
| 375 |
>>> response = HttpResponse("Text only, please.", mimetype="text/plain") |
|---|
| 376 |
|
|---|
| 377 |
But if you want to add content incrementally, you can use ``response`` as a |
|---|
| 378 |
file-like object:: |
|---|
| 379 |
|
|---|
| 380 |
>>> response = HttpResponse() |
|---|
| 381 |
>>> response.write("<p>Here's the text of the Web page.</p>") |
|---|
| 382 |
>>> response.write("<p>Here's another paragraph.</p>") |
|---|
| 383 |
|
|---|
| 384 |
You can add and delete headers using dictionary syntax:: |
|---|
| 385 |
|
|---|
| 386 |
>>> response = HttpResponse() |
|---|
| 387 |
>>> response['X-DJANGO'] = "It's the best." |
|---|
| 388 |
>>> del response['X-PHP'] |
|---|
| 389 |
>>> response['X-DJANGO'] |
|---|
| 390 |
"It's the best." |
|---|
| 391 |
|
|---|
| 392 |
Note that ``del`` doesn't raise ``KeyError`` if the header doesn't exist. |
|---|
| 393 |
|
|---|
| 394 |
Passing iterators |
|---|
| 395 |
~~~~~~~~~~~~~~~~~ |
|---|
| 396 |
|
|---|
| 397 |
Finally, you can pass ``HttpResponse`` an iterator rather than passing it |
|---|
| 398 |
hard-coded strings. If you use this technique, follow these guidelines: |
|---|
| 399 |
|
|---|
| 400 |
* The iterator should return strings. |
|---|
| 401 |
* If an ``HttpResponse`` has been initialized with an iterator as its |
|---|
| 402 |
content, you can't use the ``HttpResponse`` instance as a file-like |
|---|
| 403 |
object. Doing so will raise ``Exception``. |
|---|
| 404 |
|
|---|
| 405 |
Setting headers |
|---|
| 406 |
~~~~~~~~~~~~~~~ |
|---|
| 407 |
|
|---|
| 408 |
To set a header in your response, just treat it like a dictionary:: |
|---|
| 409 |
|
|---|
| 410 |
>>> response = HttpResponse() |
|---|
| 411 |
>>> response['Pragma'] = 'no-cache' |
|---|
| 412 |
|
|---|
| 413 |
Telling the browser to treat the response as a file attachment |
|---|
| 414 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 415 |
|
|---|
| 416 |
To tell the browser to treat the response as a file attachment, use the |
|---|
| 417 |
``mimetype`` argument and set the ``Content-Disposition`` header. For example, |
|---|
| 418 |
this is how you might return a Microsoft Excel spreadsheet:: |
|---|
| 419 |
|
|---|
| 420 |
>>> response = HttpResponse(my_data, mimetype='application/vnd.ms-excel') |
|---|
| 421 |
>>> response['Content-Disposition'] = 'attachment; filename=foo.xls' |
|---|
| 422 |
|
|---|
| 423 |
There's nothing Django-specific about the ``Content-Disposition`` header, but |
|---|
| 424 |
it's easy to forget the syntax, so we've included it here. |
|---|
| 425 |
|
|---|
| 426 |
Methods |
|---|
| 427 |
------- |
|---|
| 428 |
|
|---|
| 429 |
``__init__(content='', mimetype=None, status=200, content_type=DEFAULT_CONTENT_TYPE)`` |
|---|
| 430 |
Instantiates an ``HttpResponse`` object with the given page content (a |
|---|
| 431 |
string) and MIME type. The ``DEFAULT_CONTENT_TYPE`` is ``'text/html'``. |
|---|
| 432 |
|
|---|
| 433 |
``content`` can be an iterator or a string. If it's an iterator, it should |
|---|
| 434 |
return strings, and those strings will be joined together to form the |
|---|
| 435 |
content of the response. |
|---|
| 436 |
|
|---|
| 437 |
``status`` is the `HTTP Status code`_ for the response. |
|---|
| 438 |
|
|---|
| 439 |
**(New in Django development version)** ``content_type`` is an alias for |
|---|
| 440 |
``mimetype``. Historically, the parameter was only called ``mimetype``, |
|---|
| 441 |
but since this is actually the value included in the HTTP ``Content-Type`` |
|---|
| 442 |
header, it can also include the character set encoding, which makes it |
|---|
| 443 |
more than just a MIME type specification. If ``mimetype`` is specified |
|---|
| 444 |
(not ``None``), that value is used. Otherwise, ``content_type`` is used. If |
|---|
| 445 |
neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used. |
|---|
| 446 |
|
|---|
| 447 |
``__setitem__(header, value)`` |
|---|
| 448 |
Sets the given header name to the given value. Both ``header`` and |
|---|
| 449 |
``value`` should be strings. |
|---|
| 450 |
|
|---|
| 451 |
``__delitem__(header)`` |
|---|
| 452 |
Deletes the header with the given name. Fails silently if the header |
|---|
| 453 |
doesn't exist. Case-sensitive. |
|---|
| 454 |
|
|---|
| 455 |
``__getitem__(header)`` |
|---|
| 456 |
Returns the value for the given header name. Case-sensitive. |
|---|
| 457 |
|
|---|
| 458 |
``has_header(header)`` |
|---|
| 459 |
Returns ``True`` or ``False`` based on a case-insensitive check for a |
|---|
| 460 |
header with the given name. |
|---|
| 461 |
|
|---|
| 462 |
``set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None)`` |
|---|
| 463 |
Sets a cookie. The parameters are the same as in the `cookie Morsel`_ |
|---|
| 464 |
object in the Python standard library. |
|---|
| 465 |
|
|---|
| 466 |
* ``max_age`` should be a number of seconds, or ``None`` (default) if |
|---|
| 467 |
the cookie should last only as long as the client's browser session. |
|---|
| 468 |
* ``expires`` should be a string in the format |
|---|
| 469 |
``"Wdy, DD-Mon-YY HH:MM:SS GMT"``. |
|---|
| 470 |
* Use ``domain`` if you want to set a cross-domain cookie. For example, |
|---|
| 471 |
``domain=".lawrence.com"`` will set a cookie that is readable by |
|---|
| 472 |
the domains www.lawrence.com, blogs.lawrence.com and |
|---|
| 473 |
calendars.lawrence.com. Otherwise, a cookie will only be readable by |
|---|
| 474 |
the domain that set it. |
|---|
| 475 |
|
|---|
| 476 |
.. _`cookie Morsel`: http://www.python.org/doc/current/lib/morsel-objects.html |
|---|
| 477 |
|
|---|
| 478 |
``delete_cookie(key, path='/', domain=None)`` |
|---|
| 479 |
Deletes the cookie with the given key. Fails silently if the key doesn't |
|---|
| 480 |
exist. |
|---|
| 481 |
|
|---|
| 482 |
Due to the way cookies work, ``path`` and ``domain`` should be the same |
|---|
| 483 |
values you used in ``set_cookie()`` -- otherwise the cookie may not be deleted. |
|---|
| 484 |
|
|---|
| 485 |
``content`` |
|---|
| 486 |
Returns the content as a Python string, encoding it from a Unicode object |
|---|
| 487 |
if necessary. Note this is a property, not a method, so use ``r.content`` |
|---|
| 488 |
instead of ``r.content()``. |
|---|
| 489 |
|
|---|
| 490 |
``write(content)``, ``flush()`` and ``tell()`` |
|---|
| 491 |
These methods make an ``HttpResponse`` instance a file-like object. |
|---|
| 492 |
|
|---|
| 493 |
.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 |
|---|
| 494 |
|
|---|
| 495 |
HttpResponse subclasses |
|---|
| 496 |
----------------------- |
|---|
| 497 |
|
|---|
| 498 |
Django includes a number of ``HttpResponse`` subclasses that handle different |
|---|
| 499 |
types of HTTP responses. Like ``HttpResponse``, these subclasses live in |
|---|
| 500 |
``django.http``. |
|---|
| 501 |
|
|---|
| 502 |
``HttpResponseRedirect`` |
|---|
| 503 |
The constructor takes a single argument -- the path to redirect to. This |
|---|
| 504 |
can be a fully qualified URL (e.g. ``'http://www.yahoo.com/search/'``) or an |
|---|
| 505 |
absolute URL with no domain (e.g. ``'/search/'``). Note that this returns |
|---|
| 506 |
an HTTP status code 302. |
|---|
| 507 |
|
|---|
| 508 |
``HttpResponsePermanentRedirect`` |
|---|
| 509 |
Like ``HttpResponseRedirect``, but it returns a permanent redirect (HTTP |
|---|
| 510 |
status code 301) instead of a "found" redirect (status code 302). |
|---|
| 511 |
|
|---|
| 512 |
``HttpResponseNotModified`` |
|---|
| 513 |
The constructor doesn't take any arguments. Use this to designate that a |
|---|
| 514 |
page hasn't been modified since the user's last request (status code 304). |
|---|
| 515 |
|
|---|
| 516 |
``HttpResponseBadRequest`` |
|---|
| 517 |
**New in Django development version.** |
|---|
| 518 |
Acts just like ``HttpResponse`` but uses a 400 status code. |
|---|
| 519 |
|
|---|
| 520 |
``HttpResponseNotFound`` |
|---|
| 521 |
Acts just like ``HttpResponse`` but uses a 404 status code. |
|---|
| 522 |
|
|---|
| 523 |
``HttpResponseForbidden`` |
|---|
| 524 |
Acts just like ``HttpResponse`` but uses a 403 status code. |
|---|
| 525 |
|
|---|
| 526 |
``HttpResponseNotAllowed`` |
|---|
| 527 |
Like ``HttpResponse``, but uses a 405 status code. Takes a single, |
|---|
| 528 |
required argument: a list of permitted methods (e.g. ``['GET', 'POST']``). |
|---|
| 529 |
|
|---|
| 530 |
``HttpResponseGone`` |
|---|
| 531 |
Acts just like ``HttpResponse`` but uses a 410 status code. |
|---|
| 532 |
|
|---|
| 533 |
``HttpResponseServerError`` |
|---|
| 534 |
Acts just like ``HttpResponse`` but uses a 500 status code. |
|---|
| 535 |
|
|---|
| 536 |
Returning errors |
|---|
| 537 |
================ |
|---|
| 538 |
|
|---|
| 539 |
Returning HTTP error codes in Django is easy. We've already mentioned the |
|---|
| 540 |
``HttpResponseNotFound``, ``HttpResponseForbidden``, |
|---|
| 541 |
``HttpResponseServerError``, etc., subclasses; just return an instance of one |
|---|
| 542 |
of those subclasses instead of a normal ``HttpResponse`` in order to signify |
|---|
| 543 |
an error. For example:: |
|---|
| 544 |
|
|---|
| 545 |
def my_view(request): |
|---|
| 546 |
# ... |
|---|
| 547 |
if foo: |
|---|
| 548 |
return HttpResponseNotFound('<h1>Page not found</h1>') |
|---|
| 549 |
else: |
|---|
| 550 |
return HttpResponse('<h1>Page was found</h1>') |
|---|
| 551 |
|
|---|
| 552 |
Because 404 errors are by far the most common HTTP error, there's an easier way |
|---|
| 553 |
to handle those errors. |
|---|
| 554 |
|
|---|
| 555 |
The Http404 exception |
|---|
| 556 |
--------------------- |
|---|
| 557 |
|
|---|
| 558 |
When you return an error such as ``HttpResponseNotFound``, you're responsible |
|---|
| 559 |
for defining the HTML of the resulting error page:: |
|---|
| 560 |
|
|---|
| 561 |
return HttpResponseNotFound('<h1>Page not found</h1>') |
|---|
| 562 |
|
|---|
| 563 |
For convenience, and because it's a good idea to have a consistent 404 error page |
|---|
| 564 |
across your site, Django provides an ``Http404`` exception. If you raise |
|---|
| 565 |
``Http404`` at any point in a view function, Django will catch it and return the |
|---|
| 566 |
standard error page for your application, along with an HTTP error code 404. |
|---|
| 567 |
|
|---|
| 568 |
Example usage:: |
|---|
| 569 |
|
|---|
| 570 |
from django.http import Http404 |
|---|
| 571 |
|
|---|
| 572 |
def detail(request, poll_id): |
|---|
| 573 |
try: |
|---|
| 574 |
p = Poll.objects.get(pk=poll_id) |
|---|
| 575 |
except Poll.DoesNotExist: |
|---|
| 576 |
raise Http404 |
|---|
| 577 |
return render_to_response('polls/detail.html', {'poll': p}) |
|---|
| 578 |
|
|---|
| 579 |
In order to use the ``Http404`` exception to its fullest, you should create a |
|---|
| 580 |
template that is displayed when a 404 error is raised. This template should be |
|---|
| 581 |
called ``404.html`` and located in the top level of your template tree. |
|---|
| 582 |
|
|---|
| 583 |
Customizing error views |
|---|
| 584 |
----------------------- |
|---|
| 585 |
|
|---|
| 586 |
The 404 (page not found) view |
|---|
| 587 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 588 |
|
|---|
| 589 |
When you raise an ``Http404`` exception, Django loads a special view devoted |
|---|
| 590 |
to handling 404 errors. By default, it's the view |
|---|
| 591 |
``django.views.defaults.page_not_found``, which loads and renders the template |
|---|
| 592 |
``404.html``. |
|---|
| 593 |
|
|---|
| 594 |
This means you need to define a ``404.html`` template in your root template |
|---|
| 595 |
directory. This template will be used for all 404 errors. |
|---|
| 596 |
|
|---|
| 597 |
This ``page_not_found`` view should suffice for 99% of Web applications, but if |
|---|
| 598 |
you want to override the 404 view, you can specify ``handler404`` in your |
|---|
| 599 |
URLconf, like so:: |
|---|
| 600 |
|
|---|
| 601 |
handler404 = 'mysite.views.my_custom_404_view' |
|---|
| 602 |
|
|---|
| 603 |
Behind the scenes, Django determines the 404 view by looking for ``handler404``. |
|---|
| 604 |
By default, URLconfs contain the following line:: |
|---|
| 605 |
|
|---|
| 606 |
from django.conf.urls.defaults import * |
|---|
| 607 |
|
|---|
| 608 |
That takes care of setting ``handler404`` in the current module. As you can see |
|---|
| 609 |
in ``django/conf/urls/defaults.py``, ``handler404`` is set to |
|---|
| 610 |
``'django.views.defaults.page_not_found'`` by default. |
|---|
| 611 |
|
|---|
| 612 |
Three things to note about 404 views: |
|---|
| 613 |
|
|---|
| 614 |
* The 404 view is also called if Django doesn't find a match after checking |
|---|
| 615 |
every regular expression in the URLconf. |
|---|
| 616 |
|
|---|
| 617 |
* If you don't define your own 404 view -- and simply use the |
|---|
| 618 |
default, which is recommended -- you still have one obligation: |
|---|
| 619 |
you must create a ``404.html`` template in the root of your |
|---|
| 620 |
template directory. The default 404 view will use that template |
|---|
| 621 |
for all 404 errors. The default 404 view will pass one variable |
|---|
| 622 |
to the template: ``request_path``, which is the URL that resulted |
|---|
| 623 |
in the 404. |
|---|
| 624 |
|
|---|
| 625 |
* The 404 view is passed a ``RequestContext`` and will have access to |
|---|
| 626 |
variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` setting (e.g., |
|---|
| 627 |
``MEDIA_URL``). |
|---|
| 628 |
|
|---|
| 629 |
* If ``DEBUG`` is set to ``True`` (in your settings module), then your 404 |
|---|
| 630 |
view will never be used, and the traceback will be displayed instead. |
|---|
| 631 |
|
|---|
| 632 |
The 500 (server error) view |
|---|
| 633 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 634 |
|
|---|
| 635 |
Similarly, Django executes special-case behavior in the case of runtime errors |
|---|
| 636 |
in view code. If a view results in an exception, Django will, by default, call |
|---|
| 637 |
the view ``django.views.defaults.server_error``, which loads and renders the |
|---|
| 638 |
template ``500.html``. |
|---|
| 639 |
|
|---|
| 640 |
This means you need to define a ``500.html`` template in your root template |
|---|
| 641 |
directory. This template will be used for all server errors. The default 500 |
|---|
| 642 |
view passes no variables to this template and is rendered with an empty |
|---|
| 643 |
``Context`` to lessen the chance of additional errors. |
|---|
| 644 |
|
|---|
| 645 |
This ``server_error`` view should suffice for 99% of Web applications, but if |
|---|
| 646 |
you want to override the view, you can specify ``handler500`` in your |
|---|
| 647 |
URLconf, like so:: |
|---|
| 648 |
|
|---|
| 649 |
handler500 = 'mysite.views.my_custom_error_view' |
|---|
| 650 |
|
|---|
| 651 |
Behind the scenes, Django determines the error view by looking for ``handler500``. |
|---|
| 652 |
By default, URLconfs contain the following line:: |
|---|
| 653 |
|
|---|
| 654 |
from django.conf.urls.defaults import * |
|---|
| 655 |
|
|---|
| 656 |
That takes care of setting ``handler500`` in the current module. As you can see |
|---|
| 657 |
in ``django/conf/urls/defaults.py``, ``handler500`` is set to |
|---|
| 658 |
``'django.views.defaults.server_error'`` by default. |
|---|