123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828 |
- ==============
- URL dispatcher
- ==============
- 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 (simple regular expressions) to Python
- 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.
- Django also provides a way to translate URLs according to the active
- language. See the :ref:`internationalization documentation
- <url-internationalization>` for more information.
- .. _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 of :func:`django.conf.urls.url`
- instances.
- 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/index>`). The view gets passed the following
- arguments:
- * An instance of :class:`~django.http.HttpRequest`.
- * If the matched regular expression returned no named groups, then the
- matches from the regular expression are provided as positional arguments.
- * The keyword arguments are made up of any named groups matched by the
- regular expression, overridden by any arguments specified in the optional
- ``kwargs`` argument to :func:`django.conf.urls.url`.
- 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 url
- urlpatterns = [
- url(r'^articles/2003/$', 'news.views.special_case_2003'),
- url(r'^articles/(\d{4})/$', 'news.views.year_archive'),
- url(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
- url(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::
- from django.conf.urls import url
- urlpatterns = [
- url(r'^articles/2003/$', 'news.views.special_case_2003'),
- url(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
- url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
- url(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:
- 1. If there are any named arguments, it will use those, ignoring non-named
- arguments.
- 2. Otherwise, it will pass all non-named arguments as positional arguments.
- In both cases, any extra keyword arguments that have been given as per `Passing
- extra options to view functions`_ (below) will also be passed to the view.
- 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.
- Captured arguments are always strings
- =====================================
- 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::
- url(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.
- Specifying defaults for view arguments
- ======================================
- A convenient trick is to specify default parameters for your views' arguments.
- Here's an example URLconf and view::
- # URLconf
- from django.conf.urls import url
- urlpatterns = [
- url(r'^blog/$', 'blog.views.page'),
- url(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.
- Syntax of the urlpatterns variable
- ==================================
- ``urlpatterns`` should be a Python list of :func:`~django.conf.urls.url`
- instances.
- 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 four variables. Their
- default values should suffice for most projects, but further customization is
- possible by assigning values to them.
- See the documentation on :ref:`customizing error views
- <customizing-error-views>` for the full details.
- Such values can be set in your root URLconf. Setting these variables in any
- other URLconf will have no effect.
- Values must be callables, or strings representing the full Python import path
- to the view that should be called to handle the error condition at hand.
- The variables are:
- * ``handler404`` -- See :data:`django.conf.urls.handler404`.
- * ``handler500`` -- See :data:`django.conf.urls.handler500`.
- * ``handler403`` -- See :data:`django.conf.urls.handler403`.
- * ``handler400`` -- See :data:`django.conf.urls.handler400`.
- .. _including-other-urlconfs:
- 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 include, url
- urlpatterns = [
- # ... snip ...
- url(r'^community/', include('django_website.aggregator.urls')),
- url(r'^contact/', include('django_website.contact.urls')),
- # ... 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()`` (:func:`django.conf.urls.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 by using a list of
- :func:`~django.conf.urls.url` instances. For example, consider this URLconf::
- from django.conf.urls import include, url
- extra_patterns = [
- url(r'^reports/(?P<id>\d+)/$', 'credit.views.report'),
- url(r'^charge/$', 'credit.views.charge'),
- ]
- urlpatterns = [
- url(r'^$', 'apps.main.views.homepage'),
- url(r'^help/', include('apps.help.urls')),
- url(r'^credit/', include(extra_patterns)),
- ]
- In this example, the ``/credit/reports/`` URL will be handled by the
- ``credit.views.report()`` Django view.
- This can be used to remove redundancy from URLconfs where a single pattern
- prefix is used repeatedly. For example, consider this URLconf::
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/history/$', views.history),
- url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/edit/$', views.edit),
- url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/discuss/$', views.discuss),
- url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/permissions/$', views.permissions),
- ]
- We can improve this by stating the common path prefix only once and grouping
- the suffixes that differ::
- from django.conf.urls import include, url
- from . import views
- urlpatterns = [
- url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/', include([
- url(r'^history/$', views.history),
- url(r'^edit/$', views.edit),
- url(r'^discuss/$', views.discuss),
- url(r'^permissions/$', views.permissions),
- ])),
- ]
- .. _`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
- from django.conf.urls import include, url
- urlpatterns = [
- url(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
- ]
- # In foo/urls/blog.py
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r'^$', views.blog.index),
- url(r'^archive/$', views.blog.archive),
- ]
- In the above example, the captured ``"username"`` variable is passed to the
- included URLconf, as expected.
- .. _views-extra-options:
- Passing extra options to view functions
- =======================================
- URLconfs have a hook that lets you pass extra arguments to your view functions,
- as a Python dictionary.
- The :func:`django.conf.urls.url` function can take an optional third argument
- which should be a dictionary of extra keyword arguments to pass to the view
- function.
- For example::
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r'^blog/(?P<year>\d{4})/$', views.year_archive, {'foo': 'bar'}),
- ]
- In this example, for a request to ``/blog/2005/``, Django will call
- ``blog.views.year_archive(request, year='2005', foo='bar')``.
- This technique is used 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 :func:`~django.conf.urls.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
- from django.conf.urls import include, url
- urlpatterns = [
- url(r'^blog/', include('inner'), {'blogid': 3}),
- ]
- # inner.py
- from django.conf.urls import url
- from mysite import views
- urlpatterns = [
- url(r'^archive/$', views.archive),
- url(r'^about/$', views.about),
- ]
- Set two::
- # main.py
- from django.conf.urls import include, url
- from mysite import views
- urlpatterns = [
- url(r'^blog/', include('inner')),
- ]
- # inner.py
- from django.conf.urls import url
- urlpatterns = [
- url(r'^archive/$', views.archive, {'blogid': 3}),
- url(r'^about/$', 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::
- from django.conf.urls import url
- urlpatterns = [
- url(r'^archive/$', 'mysite.views.archive'),
- url(r'^about/$', 'mysite.views.about'),
- url(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 django.conf.urls import url
- from mysite.views import archive, about, contact
- urlpatterns = [
- url(r'^archive/$', archive),
- url(r'^about/$', about),
- url(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 django.conf.urls import url
- from mysite import views
- urlpatterns = [
- url(r'^archive/$', views.archive),
- url(r'^about/$', views.about),
- url(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/index>` must be
- imported::
- from django.conf.urls import url
- from mysite.views import ClassBasedView
- urlpatterns = [
- url(r'^myview/$', ClassBasedView.as_view()),
- ]
- Reverse resolution of URLs
- ==========================
- A common need when working on a Django project is the possibility to obtain URLs
- in their final forms either for embedding in generated content (views and assets
- URLs, URLs shown to the user, etc.) or for handling of the navigation flow on
- the server side (redirections, etc.)
- It is strongly desirable not having to hard-code these URLs (a laborious,
- non-scalable and error-prone strategy) or having to devise ad-hoc mechanisms for
- generating URLs that are parallel to the design described by the URLconf and as
- such in danger of producing stale URLs at some point.
- In other words, what's needed is a DRY mechanism. Among other advantages it
- would allow evolution of the URL design without having to go all over the
- project source code to search and replace outdated URLs.
- The piece of information we have available as a starting point to get a URL is
- an identification (e.g. the name) of the view in charge of handling it, other
- pieces of information that necessarily must participate in the lookup of the
- right URL are the types (positional, keyword) and values of the view arguments.
- Django provides a solution such that the URL mapper is the only repository of
- the URL design. You feed it with your URLconf and then it can be used in both
- directions:
- * Starting with a URL requested by the user/browser, it calls the right Django
- view providing any arguments it might need with their values as extracted from
- the URL.
- * Starting with the identification of the corresponding Django view plus the
- values of arguments that would be passed to it, obtain the associated URL.
- The first one is the usage we've been discussing in the previous sections. The
- second one is what is known as *reverse resolution of URLs*, *reverse URL
- matching*, *reverse URL lookup*, or simply *URL reversing*.
- Django provides tools for performing URL reversing that match the different
- layers where URLs are needed:
- * In templates: Using the :ttag:`url` template tag.
- * In Python code: Using the :func:`django.core.urlresolvers.reverse`
- function.
- * In higher level code related to handling of URLs of Django model instances:
- The :meth:`~django.db.models.Model.get_absolute_url` method.
- Examples
- --------
- Consider again this URLconf entry::
- from django.conf.urls import url
- urlpatterns = [
- #...
- url(r'^articles/(\d{4})/$', 'news.views.year_archive'),
- #...
- ]
- According to this design, the URL for the archive corresponding to year *nnnn*
- is ``/articles/nnnn/``.
- You can obtain these in template code by using:
- .. code-block:: html+django
- <a href="{% url 'news.views.year_archive' 2012 %}">2012 Archive</a>
- {# Or with the year in a template context variable: #}
- <ul>
- {% for yearvar in year_list %}
- <li><a href="{% url 'news.views.year_archive' yearvar %}">{{ yearvar }} Archive</a></li>
- {% endfor %}
- </ul>
- Or in Python code::
- from django.core.urlresolvers import reverse
- from django.http import HttpResponseRedirect
- def redirect_to_year(request):
- # ...
- year = 2006
- # ...
- return HttpResponseRedirect(reverse('news.views.year_archive', args=(year,)))
- If, for some reason, it was decided that the URLs where content for yearly
- article archives are published at should be changed then you would only need to
- change the entry in the URLconf.
- In some scenarios where views are of a generic nature, a many-to-one
- relationship might exist between URLs and views. For these cases the view name
- isn't a good enough identifier for it when comes the time of reversing
- URLs. Read the next section to know about the solution Django provides for this.
- .. _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::
- from django.conf.urls import url
- from mysite.views import archive
- urlpatterns = [
- url(r'^archive/(\d{4})/$', archive),
- url(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 :func:`~django.core.urlresolvers.reverse` function
- 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::
- from django.conf.urls import url
- from mysite.views import archive
- urlpatterns = [
- url(r'^archive/(\d{4})/$', archive, name="full-archive"),
- url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, name="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 :func:`django.conf.urls.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-defining-url-namespaces:
- URL namespaces
- ==============
- Introduction
- ------------
- 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:
- .. glossary::
- 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'``.
- 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'``.
- 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'``.
- .. _topics-http-reversing-url-namespaces:
- Reversing namespaced URLs
- -------------------------
- 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 :term:`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:`django.core.urlresolvers.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 :term:`instance namespace` matching the :term:`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 :term:`application namespace` in
- step 1, Django will attempt a direct lookup of the namespace as an
- :term:`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.
- Example
- ~~~~~~~
- 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'``.
- .. _namespaces-and-include:
- URL namespaces and included URLconfs
- ------------------------------------
- URL namespaces of included URLconfs can be specified in two ways.
- Firstly, you can provide the :term:`application <application namespace>` and
- :term:`instance <instance namespace>` namespaces as arguments to
- :func:`django.conf.urls.include()` when you construct your URL patterns. For
- example,::
- url(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
- This will include the URLs defined in ``apps.help.urls`` into the
- :term:`application namespace` ``'bar'``, with the :term:`instance namespace`
- ``'foo'``.
- Secondly, you can include an object that contains embedded namespace data. If
- you ``include()`` a list of :func:`django.conf.urls.url` instances,
- the URLs contained in that object will be added to the global namespace.
- However, you can also ``include()`` a 3-tuple containing::
- (<list of url() instances>, <application namespace>, <instance namespace>)
- For example::
- from django.conf.urls import include, url
- help_patterns = [
- url(r'^basic/$', 'apps.help.views.views.basic'),
- url(r'^advanced/$', 'apps.help.views.views.advanced'),
- ]
- url(r'^help/', include((help_patterns, 'bar', 'foo'))),
- This will include the nominated URL patterns into the given application and
- instance namespace.
- For example, the Django Admin is deployed as instances of
- :class:`~django.contrib.admin.AdminSite`. ``AdminSite`` objects have a ``urls``
- attribute: A 3-tuple that contains all the patterns in the corresponding admin
- site, plus the application namespace ``'admin'``, and the name of the admin
- instance. It is this ``urls`` attribute that you ``include()`` into your
- projects ``urlpatterns`` when you deploy an Admin instance.
- Be sure to pass a tuple to ``include()``. If you simply pass three arguments:
- ``include(help_patterns, 'bar', 'foo')``, Django won't throw an error but due
- to the signature of ``include()``, ``'bar'`` will be the instance namespace and
- ``'foo'`` will be the application namespace instead of vice versa.
|