~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to docs/url_dispatch.txt

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant, Eddy Mulyono
  • Date: 2008-09-16 12:18:47 UTC
  • mfrom: (1.1.5 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080916121847-mg225rg5mnsdqzr0
Tags: 1.0-1ubuntu1
* Merge from Debian (LP: #264191), remaining changes:
  - Run test suite on build.

[Eddy Mulyono]
* Update patch to workaround network test case failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
==============
2
 
URL dispatcher
3
 
==============
4
 
 
5
 
A clean, elegant URL scheme is an important detail in a high-quality Web
6
 
application. Django lets you design URLs however you want, with no framework
7
 
limitations.
8
 
 
9
 
There's no ``.php`` or ``.cgi`` required, and certainly none of that
10
 
``0,2097,1-1-1928,00`` nonsense.
11
 
 
12
 
See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for
13
 
excellent arguments on why URLs should be clean and usable.
14
 
 
15
 
.. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI
16
 
 
17
 
Overview
18
 
========
19
 
 
20
 
To design URLs for an app, you create a Python module informally called a
21
 
**URLconf** (URL configuration). This module is pure Python code and
22
 
is a simple mapping between URL patterns (as simple regular expressions) to
23
 
Python callback functions (your views).
24
 
 
25
 
This mapping can be as short or as long as needed. It can reference other
26
 
mappings. And, because it's pure Python code, it can be constructed
27
 
dynamically.
28
 
 
29
 
How Django processes a request
30
 
==============================
31
 
 
32
 
When a user requests a page from your Django-powered site, this is the
33
 
algorithm the system follows to determine which Python code to execute:
34
 
 
35
 
    1. Django looks at the ``ROOT_URLCONF`` setting in your `settings file`_.
36
 
       This should be a string representing the full Python import path to your
37
 
       URLconf. For example: ``"mydjangoapps.urls"``.
38
 
    2. Django loads that Python module and looks for the variable
39
 
       ``urlpatterns``. This should be a Python list, in the format returned by
40
 
       the function ``django.conf.urls.defaults.patterns()``.
41
 
    3. Django runs through each URL pattern, in order, and stops at the first
42
 
       one that matches the requested URL.
43
 
    4. Once one of the regexes matches, Django imports and calls the given
44
 
       view, which is a simple Python function. The view gets passed a
45
 
       `request object`_ as its first argument and any values captured in the
46
 
       regex as remaining arguments.
47
 
 
48
 
.. _settings file: ../settings/
49
 
.. _request object: ../request_response/#httprequest-objects
50
 
 
51
 
Example
52
 
=======
53
 
 
54
 
Here's a sample URLconf::
55
 
 
56
 
    from django.conf.urls.defaults import *
57
 
 
58
 
    urlpatterns = patterns('',
59
 
        (r'^articles/2003/$', 'news.views.special_case_2003'),
60
 
        (r'^articles/(\d{4})/$', 'news.views.year_archive'),
61
 
        (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
62
 
        (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
63
 
    )
64
 
 
65
 
Notes:
66
 
 
67
 
    * ``from django.conf.urls.defaults import *`` makes the ``patterns()``
68
 
      function available.
69
 
 
70
 
    * To capture a value from the URL, just put parenthesis around it.
71
 
 
72
 
    * There's no need to add a leading slash, because every URL has that. For
73
 
      example, it's ``^articles``, not ``^/articles``.
74
 
 
75
 
    * The ``'r'`` in front of each regular expression string is optional but
76
 
      recommended. It tells Python that a string is "raw" -- that nothing in
77
 
      the string should be escaped. See `Dive Into Python's explanation`_.
78
 
 
79
 
Example requests:
80
 
 
81
 
    * A request to ``/articles/2005/03/`` would match the third entry in the
82
 
      list. Django would call the function
83
 
      ``news.views.month_archive(request, '2005', '03')``.
84
 
 
85
 
    * ``/articles/2005/3/`` would not match any URL patterns, because the
86
 
      third entry in the list requires two digits for the month.
87
 
 
88
 
    * ``/articles/2003/`` would match the first pattern in the list, not the
89
 
      second one, because the patterns are tested in order, and the first one
90
 
      is the first test to pass. Feel free to exploit the ordering to insert
91
 
      special cases like this.
92
 
 
93
 
    * ``/articles/2003`` would not match any of these patterns, because each
94
 
      pattern requires that the URL end with a slash.
95
 
 
96
 
    * ``/articles/2003/03/3/`` would match the final pattern. Django would call
97
 
      the function ``news.views.article_detail(request, '2003', '03', '3')``.
98
 
 
99
 
.. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3
100
 
 
101
 
Named groups
102
 
============
103
 
 
104
 
The above example used simple, *non-named* regular-expression groups (via
105
 
parenthesis) to capture bits of the URL and pass them as *positional* arguments
106
 
to a view. In more advanced usage, it's possible to use *named*
107
 
regular-expression groups to capture URL bits and pass them as *keyword*
108
 
arguments to a view.
109
 
 
110
 
In Python regular expressions, the syntax for named regular-expression groups
111
 
is ``(?P<name>pattern)``, where ``name`` is the name of the group and
112
 
``pattern`` is some pattern to match.
113
 
 
114
 
Here's the above example URLconf, rewritten to use named groups::
115
 
 
116
 
    urlpatterns = patterns('',
117
 
        (r'^articles/2003/$', 'news.views.special_case_2003'),
118
 
        (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
119
 
        (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
120
 
        (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
121
 
    )
122
 
 
123
 
This accomplishes exactly the same thing as the previous example, with one
124
 
subtle difference: The captured values are passed to view functions as keyword
125
 
arguments rather than positional arguments. For example:
126
 
 
127
 
    * A request to ``/articles/2005/03/`` would call the function
128
 
      ``news.views.month_archive(request, year='2005', month='03')``, instead
129
 
      of ``news.views.month_archive(request, '2005', '03')``.
130
 
 
131
 
    * A request to ``/articles/2003/03/3/`` would call the function
132
 
      ``news.views.article_detail(request, year='2003', month='03', day='3')``.
133
 
 
134
 
In practice, this means your URLconfs are slightly more explicit and less prone
135
 
to argument-order bugs -- and you can reorder the arguments in your views'
136
 
function definitions. Of course, these benefits come at the cost of brevity;
137
 
some developers find the named-group syntax ugly and too verbose.
138
 
 
139
 
The matching/grouping algorithm
140
 
-------------------------------
141
 
 
142
 
Here's the algorithm the URLconf parser follows, with respect to named groups
143
 
vs. non-named groups in a regular expression:
144
 
 
145
 
If there are any named arguments, it will use those, ignoring non-named arguments.
146
 
Otherwise, it will pass all non-named arguments as positional arguments.
147
 
 
148
 
In both cases, it will pass any extra keyword arguments as keyword arguments.
149
 
See "Passing extra options to view functions" below.
150
 
 
151
 
What the URLconf searches against
152
 
=================================
153
 
 
154
 
The URLconf searches against the requested URL, as a normal Python string. This
155
 
does not include GET or POST parameters, or the domain name.
156
 
 
157
 
For example, in a request to ``http://www.example.com/myapp/``, the URLconf
158
 
will look for ``/myapp/``.
159
 
 
160
 
In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look
161
 
for ``/myapp/``.
162
 
 
163
 
The URLconf doesn't look at the request method. In other words, all request
164
 
methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same
165
 
function for the same URL.
166
 
 
167
 
Syntax of the urlpatterns variable
168
 
==================================
169
 
 
170
 
``urlpatterns`` should be a Python list, in the format returned by the function
171
 
``django.conf.urls.defaults.patterns()``. Always use ``patterns()`` to create
172
 
the ``urlpatterns`` variable.
173
 
 
174
 
Convention is to use ``from django.conf.urls.defaults import *`` at the top of
175
 
your URLconf. This gives your module access to these objects:
176
 
 
177
 
patterns
178
 
--------
179
 
 
180
 
A function that takes a prefix, and an arbitrary number of URL patterns, and
181
 
returns a list of URL patterns in the format Django needs.
182
 
 
183
 
The first argument to ``patterns()`` is a string ``prefix``. See
184
 
"The view prefix" below.
185
 
 
186
 
The remaining arguments should be tuples in this format::
187
 
 
188
 
    (regular expression, Python callback function [, optional dictionary])
189
 
 
190
 
...where ``optional dictionary`` is optional. (See
191
 
_`Passing extra options to view functions` below.)
192
 
 
193
 
handler404
194
 
----------
195
 
 
196
 
A string representing the full Python import path to the view that should be
197
 
called if none of the URL patterns match.
198
 
 
199
 
By default, this is ``'django.views.defaults.page_not_found'``. That default
200
 
value should suffice.
201
 
 
202
 
handler500
203
 
----------
204
 
 
205
 
A string representing the full Python import path to the view that should be
206
 
called in case of server errors. Server errors happen when you have runtime
207
 
errors in view code.
208
 
 
209
 
By default, this is ``'django.views.defaults.server_error'``. That default
210
 
value should suffice.
211
 
 
212
 
include
213
 
-------
214
 
 
215
 
A function that takes a full Python import path to another URLconf that should
216
 
be "included" in this place. See _`Including other URLconfs` below.
217
 
 
218
 
Notes on capturing text in URLs
219
 
===============================
220
 
 
221
 
Each captured argument is sent to the view as a plain Python string, regardless
222
 
of what sort of match the regular expression makes. For example, in this
223
 
URLconf line::
224
 
 
225
 
    (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
226
 
 
227
 
...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
228
 
an integer, even though the ``\d{4}`` will only match integer strings.
229
 
 
230
 
A convenient trick is to specify default parameters for your views' arguments.
231
 
Here's an example URLconf and view::
232
 
 
233
 
    # URLconf
234
 
    urlpatterns = patterns('',
235
 
        (r'^blog/$', 'blog.views.page'),
236
 
        (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
237
 
    )
238
 
 
239
 
    # View (in blog/views.py)
240
 
    def page(request, num="1"):
241
 
        # Output the appropriate page of blog entries, according to num.
242
 
 
243
 
In the above example, both URL patterns point to the same view --
244
 
``blog.views.page`` -- but the first pattern doesn't capture anything from the
245
 
URL. If the first pattern matches, the ``page()`` function will use its
246
 
default argument for ``num``, ``"1"``. If the second pattern matches,
247
 
``page()`` will use whatever ``num`` value was captured by the regex.
248
 
 
249
 
Performance
250
 
===========
251
 
 
252
 
Each regular expression in a ``urlpatterns`` is compiled the first time it's
253
 
accessed. This makes the system blazingly fast.
254
 
 
255
 
The view prefix
256
 
===============
257
 
 
258
 
You can specify a common prefix in your ``patterns()`` call, to cut down on
259
 
code duplication.
260
 
 
261
 
Here's the example URLconf from the `Django overview`_::
262
 
 
263
 
    from django.conf.urls.defaults import *
264
 
 
265
 
    urlpatterns = patterns('',
266
 
        (r'^articles/(\d{4})/$', 'mysite.news.views.year_archive'),
267
 
        (r'^articles/(\d{4})/(\d{2})/$', 'mysite.news.views.month_archive'),
268
 
        (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.news.views.article_detail'),
269
 
    )
270
 
 
271
 
In this example, each view has a common prefix -- ``'mysite.news.views'``.
272
 
Instead of typing that out for each entry in ``urlpatterns``, you can use the
273
 
first argument to the ``patterns()`` function to specify a prefix to apply to
274
 
each view function.
275
 
 
276
 
With this in mind, the above example can be written more concisely as::
277
 
 
278
 
    from django.conf.urls.defaults import *
279
 
 
280
 
    urlpatterns = patterns('mysite.news.views',
281
 
        (r'^articles/(\d{4})/$', 'year_archive'),
282
 
        (r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
283
 
        (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
284
 
    )
285
 
 
286
 
Note that you don't put a trailing dot (``"."``) in the prefix. Django puts
287
 
that in automatically.
288
 
 
289
 
.. _Django overview: ../overview/
290
 
 
291
 
Multiple view prefixes
292
 
----------------------
293
 
 
294
 
In practice, you'll probably end up mixing and matching views to the point
295
 
where the views in your ``urlpatterns`` won't have a common prefix. However,
296
 
you can still take advantage of the view prefix shortcut to remove duplication.
297
 
Just add multiple ``patterns()`` objects together, like this:
298
 
 
299
 
Old::
300
 
 
301
 
    from django.conf.urls.defaults import *
302
 
 
303
 
    urlpatterns = patterns('',
304
 
        (r'^/?$', 'django.views.generic.date_based.archive_index'),
305
 
        (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
306
 
        (r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
307
 
    )
308
 
 
309
 
New::
310
 
 
311
 
    from django.conf.urls.defaults import *
312
 
 
313
 
    urlpatterns = patterns('django.views.generic.date_based',
314
 
        (r'^/?$', 'archive_index'),
315
 
        (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
316
 
    )
317
 
 
318
 
    urlpatterns += patterns('weblog.views',
319
 
        (r'^tag/(?P<tag>\w+)/$', 'tag'),
320
 
    )
321
 
 
322
 
Including other URLconfs
323
 
========================
324
 
 
325
 
At any point, your ``urlpatterns`` can "include" other URLconf modules. This
326
 
essentially "roots" a set of URLs below other ones.
327
 
 
328
 
For example, here's the URLconf for the `Django website`_ itself. It includes a
329
 
number of other URLconfs::
330
 
 
331
 
    from django.conf.urls.defaults import *
332
 
 
333
 
    urlpatterns = patterns('',
334
 
        (r'^weblog/',        include('django_website.apps.blog.urls.blog')),
335
 
        (r'^documentation/', include('django_website.apps.docs.urls.docs')),
336
 
        (r'^comments/',      include('django.contrib.comments.urls.comments')),
337
 
    )
338
 
 
339
 
Note that the regular expressions in this example don't have a ``$``
340
 
(end-of-string match character) but do include a trailing slash. Whenever
341
 
Django encounters ``include()``, it chops off whatever part of the URL matched
342
 
up to that point and sends the remaining string to the included URLconf for
343
 
further processing.
344
 
 
345
 
.. _`Django website`: http://www.djangoproject.com/
346
 
 
347
 
Captured parameters
348
 
-------------------
349
 
 
350
 
An included URLconf receives any captured parameters from parent URLconfs, so
351
 
the following example is valid::
352
 
 
353
 
    # In settings/urls/main.py
354
 
    urlpatterns = patterns('',
355
 
        (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
356
 
    )
357
 
 
358
 
    # In foo/urls/blog.py
359
 
    urlpatterns = patterns('foo.views',
360
 
        (r'^$', 'blog.index'),
361
 
        (r'^archive/$', 'blog.archive'),
362
 
    )
363
 
 
364
 
In the above example, the captured ``"username"`` variable is passed to the
365
 
included URLconf, as expected.
366
 
 
367
 
Passing extra options to view functions
368
 
=======================================
369
 
 
370
 
URLconfs have a hook that lets you pass extra arguments to your view functions,
371
 
as a Python dictionary.
372
 
 
373
 
Any URLconf tuple can have an optional third element, which should be a
374
 
dictionary of extra keyword arguments to pass to the view function.
375
 
 
376
 
For example::
377
 
 
378
 
    urlpatterns = patterns('blog.views',
379
 
        (r'^/blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
380
 
    )
381
 
 
382
 
In this example, for a request to ``/blog/2005/``, Django will call the
383
 
``blog.views.year_archive()`` view, passing it these keyword arguments::
384
 
 
385
 
    year='2005', foo='bar'
386
 
 
387
 
This technique is used in `generic views`_ and in the `syndication framework`_
388
 
to pass metadata and options to views.
389
 
 
390
 
.. _generic views: ../generic_views/
391
 
.. _syndication framework: ../syndication/
392
 
 
393
 
.. admonition:: Dealing with conflicts
394
 
 
395
 
    It's possible to have a URL pattern which captures named keyword arguments,
396
 
    and also passes arguments with the same names in its dictionary of extra
397
 
    arguments. When this happens, the arguments in the dictionary will be used
398
 
    instead of the arguments captured in the URL.
399
 
 
400
 
Passing extra options to ``include()``
401
 
--------------------------------------
402
 
 
403
 
Similarly, you can pass extra options to ``include()``. When you pass extra
404
 
options to ``include()``, *each* line in the included URLconf will be passed
405
 
the extra options.
406
 
 
407
 
For example, these two URLconf sets are functionally identical:
408
 
 
409
 
Set one::
410
 
 
411
 
    # main.py
412
 
    urlpatterns = patterns('',
413
 
        (r'^blog/', include('inner'), {'blogid': 3}),
414
 
    )
415
 
 
416
 
    # inner.py
417
 
    urlpatterns = patterns('',
418
 
        (r'^archive/$', 'mysite.views.archive'),
419
 
        (r'^about/$', 'mysite.views.about'),
420
 
    )
421
 
 
422
 
Set two::
423
 
 
424
 
    # main.py
425
 
    urlpatterns = patterns('',
426
 
        (r'^blog/', include('inner')),
427
 
    )
428
 
 
429
 
    # inner.py
430
 
    urlpatterns = patterns('',
431
 
        (r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
432
 
        (r'^about/$', 'mysite.views.about', {'blogid': 3}),
433
 
    )
434
 
 
435
 
Note that extra options will *always* be passed to *every* line in the included
436
 
URLconf, regardless of whether the line's view actually accepts those options
437
 
as valid. For this reason, this technique is only useful if you're certain that
438
 
every view in the the included URLconf accepts the extra options you're passing.
439
 
 
440
 
Passing callable objects instead of strings
441
 
===========================================
442
 
 
443
 
Some developers find it more natural to pass the actual Python function object
444
 
rather than a string containing the path to its module. This alternative is
445
 
supported -- you can pass any callable object as the view.
446
 
 
447
 
For example, given this URLconf in "string" notation::
448
 
 
449
 
    urlpatterns = patterns('',
450
 
        (r'^archive/$', 'mysite.views.archive'),
451
 
        (r'^about/$', 'mysite.views.about'),
452
 
        (r'^contact/$', 'mysite.views.contact'),
453
 
    )
454
 
 
455
 
You can accomplish the same thing by passing objects rather than strings. Just
456
 
be sure to import the objects::
457
 
 
458
 
    from mysite.views import archive, about, contact
459
 
 
460
 
    urlpatterns = patterns('',
461
 
        (r'^archive/$', archive),
462
 
        (r'^about/$', about),
463
 
        (r'^contact/$', contact),
464
 
    )
465
 
 
466
 
The following example is functionally identical. It's just a bit more compact
467
 
because it imports the module that contains the views, rather than importing
468
 
each view individually::
469
 
 
470
 
    from mysite import views
471
 
 
472
 
    urlpatterns = patterns('',
473
 
        (r'^archive/$', views.archive),
474
 
        (r'^about/$', views.about),
475
 
        (r'^contact/$', views.contact),
476
 
    )
477
 
 
478
 
The style you use is up to you.
479
 
 
480
 
Note that if you use this technique -- passing objects rather than strings --
481
 
the view prefix (as explained in "The view prefix" above) will have no effect.