| ============== |
| URL dispatcher |
| ============== |
| |
| .. module:: django.core.urlresolvers |
| |
| A clean, elegant URL scheme is an important detail in a high-quality Web |
| application. Django lets you design URLs however you want, with no framework |
| limitations. |
| |
| There's no ``.php`` or ``.cgi`` required, and certainly none of that |
| ``0,2097,1-1-1928,00`` nonsense. |
| |
| See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for |
| excellent arguments on why URLs should be clean and usable. |
| |
| .. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI |
| |
| Overview |
| ======== |
| |
| To design URLs for an app, you create a Python module informally called a |
| **URLconf** (URL configuration). This module is pure Python code and |
| is a simple mapping between URL patterns (as simple regular expressions) to |
| Python callback functions (your views). |
| |
| This mapping can be as short or as long as needed. It can reference other |
| mappings. And, because it's pure Python code, it can be constructed |
| dynamically. |
| |
| .. versionadded:: 1.4 |
| Django also allows to translate URLs according to the active language. |
| This process is described in the |
| :ref:`internationalization docs <url-internationalization>`. |
| |
| .. _how-django-processes-a-request: |
| |
| How Django processes a request |
| ============================== |
| |
| When a user requests a page from your Django-powered site, this is the |
| algorithm the system follows to determine which Python code to execute: |
| |
| 1. Django determines the root URLconf module to use. Ordinarily, |
| this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming |
| ``HttpRequest`` object has an attribute called ``urlconf`` (set by |
| middleware :ref:`request processing <request-middleware>`), its value |
| will be used in place of the :setting:`ROOT_URLCONF` setting. |
| |
| 2. Django loads that Python module and looks for the variable |
| ``urlpatterns``. This should be a Python list, in the format returned by |
| the function :func:`django.conf.urls.patterns`. |
| |
| 3. Django runs through each URL pattern, in order, and stops at the first |
| one that matches the requested URL. |
| |
| 4. Once one of the regexes matches, Django imports and calls the given |
| view, which is a simple Python function (or a :doc:`class based view |
| </topics/class-based-views>`). The view gets passed an |
| :class:`~django.http.HttpRequest` as its first argument and any values |
| captured in the regex as remaining arguments. |
| |
| 5. If no regex matches, or if an exception is raised during any |
| point in this process, Django invokes an appropriate |
| error-handling view. See `Error handling`_ below. |
| |
| Example |
| ======= |
| |
| Here's a sample URLconf:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('', |
| (r'^articles/2003/$', 'news.views.special_case_2003'), |
| (r'^articles/(\d{4})/$', 'news.views.year_archive'), |
| (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), |
| (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), |
| ) |
| |
| Notes: |
| |
| * To capture a value from the URL, just put parenthesis around it. |
| |
| * There's no need to add a leading slash, because every URL has that. For |
| example, it's ``^articles``, not ``^/articles``. |
| |
| * The ``'r'`` in front of each regular expression string is optional but |
| recommended. It tells Python that a string is "raw" -- that nothing in |
| the string should be escaped. See `Dive Into Python's explanation`_. |
| |
| Example requests: |
| |
| * A request to ``/articles/2005/03/`` would match the third entry in the |
| list. Django would call the function |
| ``news.views.month_archive(request, '2005', '03')``. |
| |
| * ``/articles/2005/3/`` would not match any URL patterns, because the |
| third entry in the list requires two digits for the month. |
| |
| * ``/articles/2003/`` would match the first pattern in the list, not the |
| second one, because the patterns are tested in order, and the first one |
| is the first test to pass. Feel free to exploit the ordering to insert |
| special cases like this. |
| |
| * ``/articles/2003`` would not match any of these patterns, because each |
| pattern requires that the URL end with a slash. |
| |
| * ``/articles/2003/03/03/`` would match the final pattern. Django would call |
| the function ``news.views.article_detail(request, '2003', '03', '03')``. |
| |
| .. _Dive Into Python's explanation: http://diveintopython.net/regular_expressions/street_addresses.html#re.matching.2.3 |
| |
| Named groups |
| ============ |
| |
| The above example used simple, *non-named* regular-expression groups (via |
| parenthesis) to capture bits of the URL and pass them as *positional* arguments |
| to a view. In more advanced usage, it's possible to use *named* |
| regular-expression groups to capture URL bits and pass them as *keyword* |
| arguments to a view. |
| |
| In Python regular expressions, the syntax for named regular-expression groups |
| is ``(?P<name>pattern)``, where ``name`` is the name of the group and |
| ``pattern`` is some pattern to match. |
| |
| Here's the above example URLconf, rewritten to use named groups:: |
| |
| urlpatterns = patterns('', |
| (r'^articles/2003/$', 'news.views.special_case_2003'), |
| (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'), |
| (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'), |
| (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', 'news.views.article_detail'), |
| ) |
| |
| This accomplishes exactly the same thing as the previous example, with one |
| subtle difference: The captured values are passed to view functions as keyword |
| arguments rather than positional arguments. For example: |
| |
| * A request to ``/articles/2005/03/`` would call the function |
| ``news.views.month_archive(request, year='2005', month='03')``, instead |
| of ``news.views.month_archive(request, '2005', '03')``. |
| |
| * A request to ``/articles/2003/03/03/`` would call the function |
| ``news.views.article_detail(request, year='2003', month='03', day='03')``. |
| |
| In practice, this means your URLconfs are slightly more explicit and less prone |
| to argument-order bugs -- and you can reorder the arguments in your views' |
| function definitions. Of course, these benefits come at the cost of brevity; |
| some developers find the named-group syntax ugly and too verbose. |
| |
| The matching/grouping algorithm |
| ------------------------------- |
| |
| Here's the algorithm the URLconf parser follows, with respect to named groups |
| vs. non-named groups in a regular expression: |
| |
| If there are any named arguments, it will use those, ignoring non-named arguments. |
| Otherwise, it will pass all non-named arguments as positional arguments. |
| |
| In both cases, it will pass any extra keyword arguments as keyword arguments. |
| See "Passing extra options to view functions" below. |
| |
| What the URLconf searches against |
| ================================= |
| |
| The URLconf searches against the requested URL, as a normal Python string. This |
| does not include GET or POST parameters, or the domain name. |
| |
| For example, in a request to ``http://www.example.com/myapp/``, the URLconf |
| will look for ``myapp/``. |
| |
| In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look |
| for ``myapp/``. |
| |
| The URLconf doesn't look at the request method. In other words, all request |
| methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same |
| function for the same URL. |
| |
| Syntax of the urlpatterns variable |
| ================================== |
| |
| ``urlpatterns`` should be a Python list, in the format returned by the function |
| :func:`django.conf.urls.patterns`. Always use ``patterns()`` to create |
| the ``urlpatterns`` variable. |
| |
| ``django.conf.urls`` utility functions |
| ====================================== |
| |
| .. module:: django.conf.urls |
| |
| .. deprecated:: 1.4 |
| Starting with Django 1.4 functions ``patterns``, ``url``, ``include`` plus |
| the ``handler*`` symbols described below live in the ``django.conf.urls`` |
| module. |
| |
| Until Django 1.3 they were located in ``django.conf.urls.defaults``. You |
| still can import them from there but it will be removed in Django 1.6. |
| |
| patterns |
| -------- |
| |
| .. function:: patterns(prefix, pattern_description, ...) |
| |
| A function that takes a prefix, and an arbitrary number of URL patterns, and |
| returns a list of URL patterns in the format Django needs. |
| |
| The first argument to ``patterns()`` is a string ``prefix``. See |
| `The view prefix`_ below. |
| |
| The remaining arguments should be tuples in this format:: |
| |
| (regular expression, Python callback function [, optional dictionary [, optional name]]) |
| |
| ...where ``optional dictionary`` and ``optional name`` are optional. (See |
| `Passing extra options to view functions`_ below.) |
| |
| .. note:: |
| Because `patterns()` is a function call, it accepts a maximum of 255 |
| arguments (URL patterns, in this case). This is a limit for all Python |
| function calls. This is rarely a problem in practice, because you'll |
| typically structure your URL patterns modularly by using `include()` |
| sections. However, on the off-chance you do hit the 255-argument limit, |
| realize that `patterns()` returns a Python list, so you can split up the |
| construction of the list. |
| |
| :: |
| |
| urlpatterns = patterns('', |
| ... |
| ) |
| urlpatterns += patterns('', |
| ... |
| ) |
| |
| Python lists have unlimited size, so there's no limit to how many URL |
| patterns you can construct. The only limit is that you can only create 254 |
| at a time (the 255th argument is the initial prefix argument). |
| |
| url |
| --- |
| |
| .. function:: url(regex, view, kwargs=None, name=None, prefix='') |
| |
| You can use the ``url()`` function, instead of a tuple, as an argument to |
| ``patterns()``. This is convenient if you want to specify a name without the |
| optional extra arguments dictionary. For example:: |
| |
| urlpatterns = patterns('', |
| url(r'^index/$', index_view, name="main-view"), |
| ... |
| ) |
| |
| This function takes five arguments, most of which are optional:: |
| |
| url(regex, view, kwargs=None, name=None, prefix='') |
| |
| See `Naming URL patterns`_ for why the ``name`` parameter is useful. |
| |
| The ``prefix`` parameter has the same meaning as the first argument to |
| ``patterns()`` and is only relevant when you're passing a string as the |
| ``view`` parameter. |
| |
| include |
| ------- |
| |
| .. function:: include(<module or pattern_list>) |
| |
| A function that takes a full Python import path to another URLconf module that |
| should be "included" in this place. |
| |
| :func:`include` also accepts as an argument an iterable that returns URL |
| patterns. |
| |
| See `Including other URLconfs`_ below. |
| |
| Error handling |
| ============== |
| |
| When Django can't find a regex matching the requested URL, or when an |
| exception is raised, Django will invoke an error-handling view. The |
| views to use for these cases are specified by three variables which can |
| be set in your root URLconf. Setting these variables in any other |
| URLconf will have no effect. |
| |
| See the documentation on :ref:`customizing error views |
| <customizing-error-views>` for more details. |
| |
| handler403 |
| ---------- |
| |
| .. data:: handler403 |
| |
| A callable, or a string representing the full Python import path to the view |
| that should be called if the user doesn't have the permissions required to |
| access a resource. |
| |
| By default, this is ``'django.views.defaults.permission_denied'``. That default |
| value should suffice. |
| |
| See the documentation about :ref:`the 403 (HTTP Forbidden) view |
| <http_forbidden_view>` for more information. |
| |
| .. versionadded:: 1.4 |
| ``handler403`` is new in Django 1.4. |
| |
| handler404 |
| ---------- |
| |
| .. data:: handler404 |
| |
| A callable, or a string representing the full Python import path to the view |
| that should be called if none of the URL patterns match. |
| |
| By default, this is ``'django.views.defaults.page_not_found'``. That default |
| value should suffice. |
| |
| .. versionchanged:: 1.2 |
| Previous versions of Django only accepted strings representing import paths. |
| |
| handler500 |
| ---------- |
| |
| .. data:: handler500 |
| |
| A callable, or a string representing the full Python import path to the view |
| that should be called in case of server errors. Server errors happen when you |
| have runtime errors in view code. |
| |
| By default, this is ``'django.views.defaults.server_error'``. That default |
| value should suffice. |
| |
| .. versionchanged:: 1.2 |
| Previous versions of Django only accepted strings representing import paths. |
| |
| Notes on capturing text in URLs |
| =============================== |
| |
| Each captured argument is sent to the view as a plain Python string, regardless |
| of what sort of match the regular expression makes. For example, in this |
| URLconf line:: |
| |
| (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'), |
| |
| ...the ``year`` argument to ``news.views.year_archive()`` will be a string, not |
| an integer, even though the ``\d{4}`` will only match integer strings. |
| |
| A convenient trick is to specify default parameters for your views' arguments. |
| Here's an example URLconf and view:: |
| |
| # URLconf |
| urlpatterns = patterns('', |
| (r'^blog/$', 'blog.views.page'), |
| (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'), |
| ) |
| |
| # View (in blog/views.py) |
| def page(request, num="1"): |
| # Output the appropriate page of blog entries, according to num. |
| |
| In the above example, both URL patterns point to the same view -- |
| ``blog.views.page`` -- but the first pattern doesn't capture anything from the |
| URL. If the first pattern matches, the ``page()`` function will use its |
| default argument for ``num``, ``"1"``. If the second pattern matches, |
| ``page()`` will use whatever ``num`` value was captured by the regex. |
| |
| Performance |
| =========== |
| |
| Each regular expression in a ``urlpatterns`` is compiled the first time it's |
| accessed. This makes the system blazingly fast. |
| |
| The view prefix |
| =============== |
| |
| You can specify a common prefix in your ``patterns()`` call, to cut down on |
| code duplication. |
| |
| Here's the example URLconf from the :doc:`Django overview </intro/overview>`:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('', |
| (r'^articles/(\d{4})/$', 'news.views.year_archive'), |
| (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), |
| (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), |
| ) |
| |
| In this example, each view has a common prefix -- ``'news.views'``. |
| Instead of typing that out for each entry in ``urlpatterns``, you can use the |
| first argument to the ``patterns()`` function to specify a prefix to apply to |
| each view function. |
| |
| With this in mind, the above example can be written more concisely as:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('news.views', |
| (r'^articles/(\d{4})/$', 'year_archive'), |
| (r'^articles/(\d{4})/(\d{2})/$', 'month_archive'), |
| (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'), |
| ) |
| |
| Note that you don't put a trailing dot (``"."``) in the prefix. Django puts |
| that in automatically. |
| |
| Multiple view prefixes |
| ---------------------- |
| |
| In practice, you'll probably end up mixing and matching views to the point |
| where the views in your ``urlpatterns`` won't have a common prefix. However, |
| you can still take advantage of the view prefix shortcut to remove duplication. |
| Just add multiple ``patterns()`` objects together, like this: |
| |
| Old:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('', |
| (r'^$', 'django.views.generic.date_based.archive_index'), |
| (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'), |
| (r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'), |
| ) |
| |
| New:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('django.views.generic.date_based', |
| (r'^$', 'archive_index'), |
| (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'), |
| ) |
| |
| urlpatterns += patterns('weblog.views', |
| (r'^tag/(?P<tag>\w+)/$', 'tag'), |
| ) |
| |
| Including other URLconfs |
| ======================== |
| |
| At any point, your ``urlpatterns`` can "include" other URLconf modules. This |
| essentially "roots" a set of URLs below other ones. |
| |
| For example, here's an excerpt of the URLconf for the `Django Web site`_ |
| itself. It includes a number of other URLconfs:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| urlpatterns = patterns('', |
| # ... snip ... |
| (r'^comments/', include('django.contrib.comments.urls')), |
| (r'^community/', include('django_website.aggregator.urls')), |
| (r'^contact/', include('django_website.contact.urls')), |
| (r'^r/', include('django.conf.urls.shortcut')), |
| # ... snip ... |
| ) |
| |
| Note that the regular expressions in this example don't have a ``$`` |
| (end-of-string match character) but do include a trailing slash. Whenever |
| Django encounters ``include()``, it chops off whatever part of the URL matched |
| up to that point and sends the remaining string to the included URLconf for |
| further processing. |
| |
| Another possibility is to include additional URL patterns not by specifying the |
| URLconf Python module defining them as the `include`_ argument but by using |
| directly the pattern list as returned by `patterns`_ instead. For example:: |
| |
| from django.conf.urls import patterns, url, include |
| |
| extra_patterns = patterns('', |
| url(r'^reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'), |
| url(r'^charge/$', 'credit.views.charge', name='credit-charge'), |
| ) |
| |
| urlpatterns = patterns('', |
| url(r'^$', 'apps.main.views.homepage', name='site-homepage'), |
| (r'^help/', include('apps.help.urls')), |
| (r'^credit/', include(extra_patterns)), |
| ) |
| |
| This approach can be seen in use when you deploy an instance of the Django |
| Admin application. The Django Admin is deployed as instances of a |
| :class:`~django.contrib.admin.AdminSite`; each |
| :class:`~django.contrib.admin.AdminSite` instance has an attribute ``urls`` |
| that returns the url patterns available to that instance. It is this attribute |
| that you ``include()`` into your projects ``urlpatterns`` when you deploy the |
| admin instance. |
| |
| .. _`Django Web site`: https://www.djangoproject.com/ |
| |
| Captured parameters |
| ------------------- |
| |
| An included URLconf receives any captured parameters from parent URLconfs, so |
| the following example is valid:: |
| |
| # In settings/urls/main.py |
| urlpatterns = patterns('', |
| (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')), |
| ) |
| |
| # In foo/urls/blog.py |
| urlpatterns = patterns('foo.views', |
| (r'^$', 'blog.index'), |
| (r'^archive/$', 'blog.archive'), |
| ) |
| |
| In the above example, the captured ``"username"`` variable is passed to the |
| included URLconf, as expected. |
| |
| .. _topics-http-defining-url-namespaces: |
| |
| Defining URL namespaces |
| ----------------------- |
| |
| When you need to deploy multiple instances of a single application, it can be |
| helpful to be able to differentiate between instances. This is especially |
| important when using :ref:`named URL patterns <naming-url-patterns>`, since |
| multiple instances of a single application will share named URLs. Namespaces |
| provide a way to tell these named URLs apart. |
| |
| A URL namespace comes in two parts, both of which are strings: |
| |
| * An **application namespace**. This describes the name of the application |
| that is being deployed. Every instance of a single application will have |
| the same application namespace. For example, Django's admin application |
| has the somewhat predictable application namespace of ``admin``. |
| |
| * An **instance namespace**. This identifies a specific instance of an |
| application. Instance namespaces should be unique across your entire |
| project. However, an instance namespace can be the same as the |
| application namespace. This is used to specify a default instance of an |
| application. For example, the default Django Admin instance has an |
| instance namespace of ``admin``. |
| |
| URL Namespaces can be specified in two ways. |
| |
| Firstly, you can provide the application and instance namespace as arguments |
| to ``include()`` when you construct your URL patterns. For example,:: |
| |
| (r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')), |
| |
| This will include the URLs defined in ``apps.help.urls`` into the application |
| namespace ``bar``, with the instance namespace ``foo``. |
| |
| Secondly, you can include an object that contains embedded namespace data. If |
| you ``include()`` a ``patterns`` object, that object will be added to the |
| global namespace. However, you can also ``include()`` an object that contains |
| a 3-tuple containing:: |
| |
| (<patterns object>, <application namespace>, <instance namespace>) |
| |
| This will include the nominated URL patterns into the given application and |
| instance namespace. For example, the ``urls`` attribute of Django's |
| :class:`~django.contrib.admin.AdminSite` object returns a 3-tuple that contains |
| all the patterns in an admin site, plus the name of the admin instance, and the |
| application namespace ``admin``. |
| |
| Once you have defined namespaced URLs, you can reverse them. For details on |
| reversing namespaced urls, see the documentation on :ref:`reversing namespaced |
| URLs <topics-http-reversing-url-namespaces>`. |
| |
| Passing extra options to view functions |
| ======================================= |
| |
| URLconfs have a hook that lets you pass extra arguments to your view functions, |
| as a Python dictionary. |
| |
| Any URLconf tuple can have an optional third element, which should be a |
| dictionary of extra keyword arguments to pass to the view function. |
| |
| For example:: |
| |
| urlpatterns = patterns('blog.views', |
| (r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}), |
| ) |
| |
| In this example, for a request to ``/blog/2005/``, Django will call the |
| ``blog.views.year_archive()`` view, passing it these keyword arguments:: |
| |
| year='2005', foo='bar' |
| |
| This technique is used in :doc:`generic views </ref/generic-views>` and in the |
| :doc:`syndication framework </ref/contrib/syndication>` to pass metadata and |
| options to views. |
| |
| .. admonition:: Dealing with conflicts |
| |
| It's possible to have a URL pattern which captures named keyword arguments, |
| and also passes arguments with the same names in its dictionary of extra |
| arguments. When this happens, the arguments in the dictionary will be used |
| instead of the arguments captured in the URL. |
| |
| Passing extra options to ``include()`` |
| -------------------------------------- |
| |
| Similarly, you can pass extra options to ``include()``. When you pass extra |
| options to ``include()``, *each* line in the included URLconf will be passed |
| the extra options. |
| |
| For example, these two URLconf sets are functionally identical: |
| |
| Set one:: |
| |
| # main.py |
| urlpatterns = patterns('', |
| (r'^blog/', include('inner'), {'blogid': 3}), |
| ) |
| |
| # inner.py |
| urlpatterns = patterns('', |
| (r'^archive/$', 'mysite.views.archive'), |
| (r'^about/$', 'mysite.views.about'), |
| ) |
| |
| Set two:: |
| |
| # main.py |
| urlpatterns = patterns('', |
| (r'^blog/', include('inner')), |
| ) |
| |
| # inner.py |
| urlpatterns = patterns('', |
| (r'^archive/$', 'mysite.views.archive', {'blogid': 3}), |
| (r'^about/$', 'mysite.views.about', {'blogid': 3}), |
| ) |
| |
| Note that extra options will *always* be passed to *every* line in the included |
| URLconf, regardless of whether the line's view actually accepts those options |
| as valid. For this reason, this technique is only useful if you're certain that |
| every view in the included URLconf accepts the extra options you're passing. |
| |
| Passing callable objects instead of strings |
| =========================================== |
| |
| Some developers find it more natural to pass the actual Python function object |
| rather than a string containing the path to its module. This alternative is |
| supported -- you can pass any callable object as the view. |
| |
| For example, given this URLconf in "string" notation:: |
| |
| urlpatterns = patterns('', |
| (r'^archive/$', 'mysite.views.archive'), |
| (r'^about/$', 'mysite.views.about'), |
| (r'^contact/$', 'mysite.views.contact'), |
| ) |
| |
| You can accomplish the same thing by passing objects rather than strings. Just |
| be sure to import the objects:: |
| |
| from mysite.views import archive, about, contact |
| |
| urlpatterns = patterns('', |
| (r'^archive/$', archive), |
| (r'^about/$', about), |
| (r'^contact/$', contact), |
| ) |
| |
| The following example is functionally identical. It's just a bit more compact |
| because it imports the module that contains the views, rather than importing |
| each view individually:: |
| |
| from mysite import views |
| |
| urlpatterns = patterns('', |
| (r'^archive/$', views.archive), |
| (r'^about/$', views.about), |
| (r'^contact/$', views.contact), |
| ) |
| |
| The style you use is up to you. |
| |
| Note that if you use this technique -- passing objects rather than strings -- |
| the view prefix (as explained in "The view prefix" above) will have no effect. |
| |
| Note that :doc:`class based views</topics/class-based-views>` must be |
| imported:: |
| |
| from mysite.views import ClassBasedView |
| |
| urlpatterns = patterns('', |
| (r'^myview/$', ClassBasedView.as_view()), |
| ) |
| |
| .. _naming-url-patterns: |
| |
| Naming URL patterns |
| =================== |
| |
| It's fairly common to use the same view function in multiple URL patterns in |
| your URLconf. For example, these two URL patterns both point to the ``archive`` |
| view:: |
| |
| urlpatterns = patterns('', |
| (r'^archive/(\d{4})/$', archive), |
| (r'^archive-summary/(\d{4})/$', archive, {'summary': True}), |
| ) |
| |
| This is completely valid, but it leads to problems when you try to do reverse |
| URL matching (through the ``permalink()`` decorator or the :ttag:`url` template |
| tag). Continuing this example, if you wanted to retrieve the URL for the |
| ``archive`` view, Django's reverse URL matcher would get confused, because *two* |
| URL patterns point at that view. |
| |
| To solve this problem, Django supports **named URL patterns**. That is, you can |
| give a name to a URL pattern in order to distinguish it from other patterns |
| using the same view and parameters. Then, you can use this name in reverse URL |
| matching. |
| |
| Here's the above example, rewritten to use named URL patterns:: |
| |
| urlpatterns = patterns('', |
| url(r'^archive/(\d{4})/$', archive, name="full-archive"), |
| url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"), |
| ) |
| |
| With these names in place (``full-archive`` and ``arch-summary``), you can |
| target each pattern individually by using its name: |
| |
| .. code-block:: html+django |
| |
| {% url arch-summary 1945 %} |
| {% url full-archive 2007 %} |
| |
| Even though both URL patterns refer to the ``archive`` view here, using the |
| ``name`` parameter to ``url()`` allows you to tell them apart in templates. |
| |
| The string used for the URL name can contain any characters you like. You are |
| not restricted to valid Python names. |
| |
| .. note:: |
| |
| When you name your URL patterns, make sure you use names that are unlikely |
| to clash with any other application's choice of names. If you call your URL |
| pattern ``comment``, and another application does the same thing, there's |
| no guarantee which URL will be inserted into your template when you use |
| this name. |
| |
| Putting a prefix on your URL names, perhaps derived from the application |
| name, will decrease the chances of collision. We recommend something like |
| ``myapp-comment`` instead of ``comment``. |
| |
| .. _topics-http-reversing-url-namespaces: |
| |
| URL namespaces |
| -------------- |
| |
| Namespaced URLs are specified using the ``:`` operator. For example, the main |
| index page of the admin application is referenced using ``admin:index``. This |
| indicates a namespace of ``admin``, and a named URL of ``index``. |
| |
| Namespaces can also be nested. The named URL ``foo:bar:whiz`` would look for |
| a pattern named ``whiz`` in the namespace ``bar`` that is itself defined within |
| the top-level namespace ``foo``. |
| |
| When given a namespaced URL (e.g. ``myapp:index``) to resolve, Django splits |
| the fully qualified name into parts, and then tries the following lookup: |
| |
| 1. First, Django looks for a matching application namespace (in this |
| example, ``myapp``). This will yield a list of instances of that |
| application. |
| |
| 2. If there is a *current* application defined, Django finds and returns |
| the URL resolver for that instance. The *current* application can be |
| specified as an attribute on the template context - applications that |
| expect to have multiple deployments should set the ``current_app`` |
| attribute on any ``Context`` or ``RequestContext`` that is used to |
| render a template. |
| |
| The current application can also be specified manually as an argument |
| to the :func:`reverse()` function. |
| |
| 3. If there is no current application. Django looks for a default |
| application instance. The default application instance is the instance |
| that has an instance namespace matching the application namespace (in |
| this example, an instance of the ``myapp`` called ``myapp``). |
| |
| 4. If there is no default application instance, Django will pick the last |
| deployed instance of the application, whatever its instance name may be. |
| |
| 5. If the provided namespace doesn't match an application namespace in |
| step 1, Django will attempt a direct lookup of the namespace as an |
| instance namespace. |
| |
| If there are nested namespaces, these steps are repeated for each part of the |
| namespace until only the view name is unresolved. The view name will then be |
| resolved into a URL in the namespace that has been found. |
| |
| To show this resolution strategy in action, consider an example of two instances |
| of ``myapp``: one called ``foo``, and one called ``bar``. ``myapp`` has a main |
| index page with a URL named `index`. Using this setup, the following lookups are |
| possible: |
| |
| * If one of the instances is current - say, if we were rendering a utility page |
| in the instance ``bar`` - ``myapp:index`` will resolve to the index page of |
| the instance ``bar``. |
| |
| * If there is no current instance - say, if we were rendering a page |
| somewhere else on the site - ``myapp:index`` will resolve to the last |
| registered instance of ``myapp``. Since there is no default instance, |
| the last instance of ``myapp`` that is registered will be used. This could |
| be ``foo`` or ``bar``, depending on the order they are introduced into the |
| urlpatterns of the project. |
| |
| * ``foo:index`` will always resolve to the index page of the instance ``foo``. |
| |
| If there was also a default instance - i.e., an instance named `myapp` - the |
| following would happen: |
| |
| * If one of the instances is current - say, if we were rendering a utility page |
| in the instance ``bar`` - ``myapp:index`` will resolve to the index page of |
| the instance ``bar``. |
| |
| * If there is no current instance - say, if we were rendering a page somewhere |
| else on the site - ``myapp:index`` will resolve to the index page of the |
| default instance. |
| |
| * ``foo:index`` will again resolve to the index page of the instance ``foo``. |
| |
| |
| ``django.core.urlresolvers`` utility functions |
| ============================================== |
| |
| .. currentmodule:: django.core.urlresolvers |
| |
| reverse() |
| --------- |
| |
| If you need to use something similar to the :ttag:`url` template tag in |
| your code, Django provides the following function (in the |
| :mod:`django.core.urlresolvers` module): |
| |
| .. function:: reverse(viewname, [urlconf=None, args=None, kwargs=None, current_app=None]) |
| |
| ``viewname`` is either the function name (either a function reference, or the |
| string version of the name, if you used that form in ``urlpatterns``) or the |
| `URL pattern name`_. Normally, you won't need to worry about the |
| ``urlconf`` parameter and will only pass in the positional and keyword |
| arguments to use in the URL matching. For example:: |
| |
| from django.core.urlresolvers import reverse |
| |
| def myview(request): |
| return HttpResponseRedirect(reverse('arch-summary', args=[1945])) |
| |
| .. _URL pattern name: `Naming URL patterns`_ |
| |
| The ``reverse()`` function can reverse a large variety of regular expression |
| patterns for URLs, but not every possible one. The main restriction at the |
| moment is that the pattern cannot contain alternative choices using the |
| vertical bar (``"|"``) character. You can quite happily use such patterns for |
| matching against incoming URLs and sending them off to views, but you cannot |
| reverse such patterns. |
| |
| The ``current_app`` argument allows you to provide a hint to the resolver |
| indicating the application to which the currently executing view belongs. |
| This ``current_app`` argument is used as a hint to resolve application |
| namespaces into URLs on specific application instances, according to the |
| :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`. |
| |
| You can use ``kwargs`` instead of ``args``. For example:: |
| |
| >>> reverse('admin:app_list', kwargs={'app_label': 'auth'}) |
| '/admin/auth/' |
| |
| ``args`` and ``kwargs`` cannot be passed to ``reverse()`` at the same time. |
| |
| .. admonition:: Make sure your views are all correct. |
| |
| As part of working out which URL names map to which patterns, the |
| ``reverse()`` function has to import all of your URLconf files and examine |
| the name of each view. This involves importing each view function. If |
| there are *any* errors whilst importing any of your view functions, it |
| will cause ``reverse()`` to raise an error, even if that view function is |
| not the one you are trying to reverse. |
| |
| Make sure that any views you reference in your URLconf files exist and can |
| be imported correctly. Do not include lines that reference views you |
| haven't written yet, because those views will not be importable. |
| |
| .. note:: |
| |
| The string returned by :meth:`~django.core.urlresolvers.reverse` is already |
| :ref:`urlquoted <uri-and-iri-handling>`. For example:: |
| |
| >>> reverse('cities', args=[u'Orléans']) |
| '.../Orl%C3%A9ans/' |
| |
| Applying further encoding (such as :meth:`~django.utils.http.urlquote` or |
| ``urllib.quote``) to the output of :meth:`~django.core.urlresolvers.reverse` |
| may produce undesirable results. |
| |
| reverse_lazy() |
| -------------- |
| |
| .. versionadded:: 1.4 |
| |
| A lazily evaluated version of `reverse()`_. |
| |
| .. function:: reverse_lazy(viewname, [urlconf=None, args=None, kwargs=None, current_app=None]) |
| |
| It is useful for when you need to use a URL reversal before your project's |
| URLConf is loaded. Some common cases where this function is necessary are: |
| |
| * providing a reversed URL as the ``url`` attribute of a generic class-based |
| view. |
| |
| * providing a reversed URL to a decorator (such as the ``login_url`` argument |
| for the :func:`django.contrib.auth.decorators.permission_required` |
| decorator). |
| |
| * providing a reversed URL as a default value for a parameter in a function's |
| signature. |
| |
| resolve() |
| --------- |
| |
| The :func:`django.core.urlresolvers.resolve` function can be used for |
| resolving URL paths to the corresponding view functions. It has the |
| following signature: |
| |
| .. function:: resolve(path, urlconf=None) |
| |
| ``path`` is the URL path you want to resolve. As with |
| :func:`~django.core.urlresolvers.reverse`, you don't need to |
| worry about the ``urlconf`` parameter. The function returns a |
| :class:`ResolverMatch` object that allows you |
| to access various meta-data about the resolved URL. |
| |
| If the URL does not resolve, the function raises an |
| :class:`~django.http.Http404` exception. |
| |
| .. class:: ResolverMatch |
| |
| .. attribute:: ResolverMatch.func |
| |
| The view function that would be used to serve the URL |
| |
| .. attribute:: ResolverMatch.args |
| |
| The arguments that would be passed to the view function, as |
| parsed from the URL. |
| |
| .. attribute:: ResolverMatch.kwargs |
| |
| The keyword arguments that would be passed to the view |
| function, as parsed from the URL. |
| |
| .. attribute:: ResolverMatch.url_name |
| |
| The name of the URL pattern that matches the URL. |
| |
| .. attribute:: ResolverMatch.app_name |
| |
| The application namespace for the URL pattern that matches the |
| URL. |
| |
| .. attribute:: ResolverMatch.namespace |
| |
| The instance namespace for the URL pattern that matches the |
| URL. |
| |
| .. attribute:: ResolverMatch.namespaces |
| |
| The list of individual namespace components in the full |
| instance namespace for the URL pattern that matches the URL. |
| i.e., if the namespace is ``foo:bar``, then namespaces will be |
| ``['foo', 'bar']``. |
| |
| A :class:`ResolverMatch` object can then be interrogated to provide |
| information about the URL pattern that matches a URL:: |
| |
| # Resolve a URL |
| match = resolve('/some/path/') |
| # Print the URL pattern that matches the URL |
| print match.url_name |
| |
| A :class:`ResolverMatch` object can also be assigned to a triple:: |
| |
| func, args, kwargs = resolve('/some/path/') |
| |
| .. versionchanged:: 1.3 |
| Triple-assignment exists for backwards-compatibility. Prior to |
| Django 1.3, :func:`~django.core.urlresolvers.resolve` returned a |
| triple containing (view function, arguments, keyword arguments); |
| the :class:`ResolverMatch` object (as well as the namespace and pattern |
| information it provides) is not available in earlier Django releases. |
| |
| One possible use of :func:`~django.core.urlresolvers.resolve` would be to test |
| whether a view would raise a ``Http404`` error before redirecting to it:: |
| |
| from urlparse import urlparse |
| from django.core.urlresolvers import resolve |
| from django.http import HttpResponseRedirect, Http404 |
| |
| def myview(request): |
| next = request.META.get('HTTP_REFERER', None) or '/' |
| response = HttpResponseRedirect(next) |
| |
| # modify the request and response as required, e.g. change locale |
| # and set corresponding locale cookie |
| |
| view, args, kwargs = resolve(urlparse(next)[2]) |
| kwargs['request'] = request |
| try: |
| view(*args, **kwargs) |
| except Http404: |
| return HttpResponseRedirect('/') |
| return response |
| |
| |
| permalink() |
| ----------- |
| |
| The :func:`django.db.models.permalink` decorator is useful for writing short |
| methods that return a full URL path. For example, a model's |
| ``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more. |
| |
| get_script_prefix() |
| ------------------- |
| |
| .. function:: get_script_prefix() |
| |
| Normally, you should always use :func:`~django.core.urlresolvers.reverse` or |
| :func:`~django.db.models.permalink` to define URLs within your application. |
| However, if your application constructs part of the URL hierarchy itself, you |
| may occasionally need to generate URLs. In that case, you need to be able to |
| find the base URL of the Django project within its Web server |
| (normally, :func:`~django.core.urlresolvers.reverse` takes care of this for |
| you). In that case, you can call ``get_script_prefix()``, which will return the |
| script prefix portion of the URL for your Django project. If your Django |
| project is at the root of its Web server, this is always ``"/"``, but it can be |
| changed, for instance by using ``django.root`` (see :doc:`How to use |
| Django with Apache and mod_python </howto/deployment/modpython>`). |