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
9 There's no ``.php`` or ``.cgi`` required, and certainly none of that
10 ``0,2097,1-1-1928,00`` nonsense.
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.
15 .. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI
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).
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
29 How Django processes a request
30 ==============================
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:
35 1. The system looks at the ``ROOT_URLCONF`` setting in your
36 `settings file`_. This should be a string representing the full Python
37 import path to your URLconf. For example: ``"mydjangoapps.urls"``.
38 2. The system loads that Python module and looks for the variable
39 ``urlpatterns``. This should be a Python list, in the format returned
40 by the function ``django.conf.urls.defaults.patterns()``.
41 3. The system runs through each URL pattern, in order, and stops at the
42 first 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`_ and any values captured in the regex as function
48 .. _settings file: http://www.djangoproject.com/documentation/settings/
49 .. _request object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
54 **This syntax is new in the Django development version.** See "Named groups"
55 below if you're using Django 0.90.
57 Here's a sample URLconf::
59 from django.conf.urls.defaults import *
61 urlpatterns = patterns('',
62 (r'^articles/2003/$', 'news.views.special_case_2003'),
63 (r'^articles/(\d{4})/$', 'news.views.year_archive'),
64 (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
65 (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
70 * ``from django.conf.urls.defaults import *`` makes the ``patterns``
73 * To capture a value from the URL, just put parenthesis around it.
75 * There's no need to add a leading slash, because every URL has that. For
76 example, it's ``^articles``, not ``^/articles``.
78 * The ``"r"`` in front of each regular expression string is optional but
79 recommended. It tells Python that a string is "raw" -- that nothing in
80 the string should be escaped. See `Dive Into Python's explanation`_.
84 * A request to ``/articles/2005/03/`` would match the third entry in the
85 list. Django would call the function
86 ``news.views.month_archive(request, '2005', '03')``.
88 * ``/articles/2005/3/`` would not match any URL patterns, because the
89 third entry in the list requires two digits for the month.
91 * ``/articles/2003/`` would match the first pattern in the list, not the
92 second one, because the patterns are tested in order, and the first one
93 is the first test to pass. Feel free to exploit the ordering to insert
94 special cases like this.
96 * ``/articles/2003`` would not match any of these patterns, because each
97 pattern requires that the URL end with a slash.
99 * ``/articles/2003/03/3/`` would match the final pattern. Django would call
100 the function ``news.views.article_detail(request, '2003', '03', '3')``.
102 .. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3
107 The above example used simple, *non-named* regular-expression groups (via
108 parenthesis) to capture bits of the URL and pass them as *positional* arguments
109 to a view. In more advanced usage, it's possible to use *named*
110 regular-expression groups to capture URL bits and pass them as *keyword*
113 (Note that support for non-named regex groups is a new feature in the Django
114 development version. Django 0.90 requires named groups.)
116 In Python regular expressions, the syntax for named regular-expression groups
117 is ``(?P<name>pattern)``, where ``name`` is the name of the group and
118 ``pattern`` is some pattern to match.
120 Here's the above example URLconf, rewritten to use named groups::
122 urlpatterns = patterns('',
123 (r'^articles/2003/$', 'news.views.special_case_2003'),
124 (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
125 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
126 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
129 This accomplishes exactly the same thing as the previous example, with one
130 subtle difference: The captured values are passed as keyword arguments rather
131 than positional arguments. For example:
133 * A request to ``/articles/2005/03/`` would call the function
134 ``news.views.month_archive(request, year='2005', month='03')``, instead
135 of ``news.views.month_archive(request, '2005', '03')``.
137 * A request to ``/articles/2003/03/3/`` would call the function
138 ``news.views.article_detail(request, year='2003', month='03', day='3')``.
140 In practice, this means your URLconfs are slightly more explicit and less prone
141 to argument-order bugs -- and you can reorder the arguments in your views'
142 function definitions. Of course, these benefits come at the cost of brevity;
143 some folks find the named-group syntax ugly and too verbose.
145 The matching/grouping algorithm
146 -------------------------------
148 Here's the algorithm the URLconf parser follows, with respect to named groups
149 vs. non-named groups in a regular expression:
151 * If there are any named groups, it will use those as keyword arguments,
152 ignoring any non-named groups.
153 * Otherwise, it will pass all non-named groups as positional arguments.
154 * In both cases, it will pass any extra
156 If there are any named arguments, it will use those, ignoring non-named arguments.
157 Otherwise, it will pass all non-named arguments as positional arguments.
159 In both cases, it will pass any extra keyword arguments as keyword arguments.
160 See "Passing extra options to view functions" below.
162 What the URLconf searches against
163 =================================
165 The URLconf searches against the requested URL, as a normal Python string. This
166 does not include GET or POST parameters, or the domain name.
168 For example, in a request to ``http://www.example.com/myapp/``, the URLconf
169 will look for ``/myapp/``.
171 In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look
174 Syntax of the urlpatterns variable
175 ==================================
177 ``urlpatterns`` should be a Python list, in the format returned by the function
178 ``django.conf.urls.defaults.patterns()``. Always use ``patterns()`` to create
179 the ``urlpatterns`` variable.
181 Convention is to use ``from django.conf.urls.defaults import *`` at the top of
182 your URLconf. This gives your module access to these objects:
187 A function that takes a prefix an arbitrary number of URL patterns and returns
188 a list of URL patterns in the format Django needs.
190 The first argument to ``patterns()`` is a string ``prefix``. See
191 "The view prefix" below.
193 The remaining arguments should be tuples in this format::
195 (regular expression, Python callback function [, optional dictionary])
197 ...where ``dictionary_of_extra_arguments`` is optional. (See
198 "Passing extra options to view functions" below.)
203 A string representing the full Python import path to the view that should be
204 called if none of the URL patterns match.
206 By default, this is ``'django.views.defaults.page_not_found'``. That default
207 value should suffice.
212 A string representing the full Python import path to the view that should be
213 called in case of server errors. Server errors happen when you have runtime
216 By default, this is ``'django.views.defaults.server_error'``. That default
217 value should suffice.
222 A function that takes a full Python import path to another URLconf that should
223 be "included" in this place. See "Including other URLconfs" below.
225 Notes on capturing text in URLs
226 ===============================
228 Each captured argument is sent to the view as a plain Python string, regardless
229 of what sort of match the regular expression makes. For example, in this
232 (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
234 ...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
235 an integer, even though the ``\d{4}`` will only match integer strings.
237 A convenient trick is to specify default parameters for your views' arguments.
238 Here's an example URLconf and view::
241 urlpatterns = patterns('',
242 (r'^blog/$', 'blog.views.page'),
243 (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
246 # View (in blog/views.py)
247 def page(request, num="1"):
248 # Output the appropriate page of blog entries, according to num.
250 In the above example, both URL patterns point to the same view --
251 ``blog.views.page`` -- but the first pattern doesn't capture anything from the
252 URL. If the first pattern matches, the ``page()`` function will use its
253 default argument for ``num``, ``"1"``. If the second pattern matches,
254 ``page()`` will use whatever ``num`` value was captured by the regex.
259 Each regular expression in a ``urlpatterns`` is compiled the first time it's
260 accessed. This makes the system blazingly fast.
265 You can specify a common prefix in your ``patterns()`` call, to cut down on
268 Here's the example URLconf from the `Django overview`_::
270 from django.conf.urls.defaults import *
272 urlpatterns = patterns('',
273 (r'^articles/(?P<year>\d{4})/$', 'myproject.news.views.year_archive'),
274 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'myproject.news.views.month_archive'),
275 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'myproject.news.views.article_detail'),
278 In this example, each view has a common prefix -- ``"myproject.news.views"``.
279 Instead of typing that out for each entry in ``urlpatterns``, you can use the
280 first argument to the ``patterns()`` function to specify a prefix to apply to
283 With this in mind, the above example can be written more concisely as::
285 from django.conf.urls.defaults import *
287 urlpatterns = patterns('myproject.news.views',
288 (r'^articles/(?P<year>\d{4})/$', 'year_archive'),
289 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'month_archive'),
290 (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'article_detail'),
293 Note that you don't put a trailing dot (``"."``) in the prefix. Django puts
294 that in automatically.
296 .. _Django overview: http://www.djangoproject.com/documentation/overview/
298 Including other URLconfs
299 ========================
301 At any point, your ``urlpatterns`` can "include" other URLconf modules. This
302 essentially "roots" a set of URLs below other ones.
304 For example, here's the URLconf for the `Django website`_ itself. It includes a
305 number of other URLconfs::
307 from django.conf.urls.defaults import *
309 urlpatterns = patterns('',
310 (r'^weblog/', include('django_website.apps.blog.urls.blog')),
311 (r'^documentation/', include('django_website.apps.docs.urls.docs')),
312 (r'^comments/', include('django.contrib.comments.urls.comments')),
313 (r'^rss/', include('django.conf.urls.rss')),
316 Note that the regular expressions in this example don't have a ``$``
317 (end-of-string match character) but do include a trailing slash. Whenever
318 Django encounters ``include()``, it chops off whatever part of the URL matched
319 up to that point and sends the remaining string to the included URLconf for
322 .. _`Django website`: http://www.djangoproject.com/
327 An included URLconf receives any captured parameters from parent URLconfs, so
328 the following example is valid::
330 # In settings/urls/main.py
331 urlpatterns = patterns('',
332 (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
335 # In foo/urls/blog.py
336 urlpatterns = patterns('foo.views'
337 (r'^$', 'blog.index'),
338 (r'^archive/$', 'blog.archive'),
341 In the above example, the captured ``"username"`` variable is passed to the
342 included URLconf, as expected.
344 Passing extra options to view functions
345 =======================================
347 URLconfs have a hook that lets you pass extra arguments to your view functions,
348 as a Python dictionary.
350 Any URLconf tuple can have an optional third element, which should be a
351 dictionary of extra keyword arguments to pass to the view function.
355 urlpatterns = patterns('blog.views',
356 (r'^/blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
359 In this example, for a request to ``/blog/2005/``, Django will call the
360 ``blog.views.year_archive()`` view, passing it these keyword arguments::
362 year='2005', foo='bar'
364 This technique is used in `generic views`_ and in the `syndication framework`_
365 to pass metadata and options to views.
367 .. _generic views: http://www.djangoproject.com/documentation/generic_views/
368 .. _syndication framework: http://www.djangoproject.com/documentation/syndication/