Added section about URL reversion to URL mapper document.
This commit is contained in:
parent
34a736b752
commit
ec1aad1671
|
@ -226,7 +226,7 @@ Hooking the wizard into a URLconf
|
|||
---------------------------------
|
||||
|
||||
Finally, we need to specify which forms to use in the wizard, and then
|
||||
deploy the new :class:`WizardView` object at an URL in the ``urls.py``. The
|
||||
deploy the new :class:`WizardView` object at a URL in the ``urls.py``. The
|
||||
wizard's :meth:`as_view` method takes a list of your
|
||||
:class:`~django.forms.Form` classes as an argument during instantiation::
|
||||
|
||||
|
|
|
@ -494,12 +494,16 @@ defined. If it makes sense for your model's instances to each have a unique
|
|||
URL, you should define ``get_absolute_url()``.
|
||||
|
||||
It's good practice to use ``get_absolute_url()`` in templates, instead of
|
||||
hard-coding your objects' URLs. For example, this template code is bad::
|
||||
hard-coding your objects' URLs. For example, this template code is bad:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
<!-- BAD template code. Avoid! -->
|
||||
<a href="/people/{{ object.id }}/">{{ object.name }}</a>
|
||||
|
||||
This template code is much better::
|
||||
This template code is much better:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
|
||||
|
||||
|
@ -535,7 +539,9 @@ pattern name) and a list of position or keyword arguments and uses the URLconf
|
|||
patterns to construct the correct, full URL. It returns a string for the
|
||||
correct URL, with all parameters substituted in the correct positions.
|
||||
|
||||
The ``permalink`` decorator is a Python-level equivalent to the :ttag:`url` template tag and a high-level wrapper for the :func:`django.core.urlresolvers.reverse()` function.
|
||||
The ``permalink`` decorator is a Python-level equivalent to the :ttag:`url`
|
||||
template tag and a high-level wrapper for the
|
||||
:func:`django.core.urlresolvers.reverse()` function.
|
||||
|
||||
An example should make it clear how to use ``permalink()``. Suppose your URLconf
|
||||
contains a line such as::
|
||||
|
|
|
@ -997,7 +997,7 @@ refer to the name of the pattern in the ``url`` tag instead of using the
|
|||
path to the view.
|
||||
|
||||
Note that if the URL you're reversing doesn't exist, you'll get an
|
||||
:exc:`^django.core.urlresolvers.NoReverseMatch` exception raised, which will
|
||||
:exc:`~django.core.urlresolvers.NoReverseMatch` exception raised, which will
|
||||
cause your site to display an error page.
|
||||
|
||||
If you'd like to retrieve a URL without displaying it, you can use a slightly
|
||||
|
|
|
@ -8,8 +8,7 @@ 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):
|
||||
your code, Django provides the following function:
|
||||
|
||||
.. function:: reverse(viewname, [urlconf=None, args=None, kwargs=None, current_app=None])
|
||||
|
||||
|
@ -59,15 +58,15 @@ You can use ``kwargs`` instead of ``args``. For example::
|
|||
|
||||
.. note::
|
||||
|
||||
The string returned by :meth:`~django.core.urlresolvers.reverse` is already
|
||||
The string returned by ``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.
|
||||
``urllib.quote``) to the output of ``reverse()`` may produce undesirable
|
||||
results.
|
||||
|
||||
reverse_lazy()
|
||||
--------------
|
||||
|
@ -94,9 +93,8 @@ URLConf is loaded. Some common cases where this function is necessary are:
|
|||
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:
|
||||
The ``resolve()`` function can be used for resolving URL paths to the
|
||||
corresponding view functions. It has the following signature:
|
||||
|
||||
.. function:: resolve(path, urlconf=None)
|
||||
|
||||
|
@ -184,7 +182,7 @@ whether a view would raise a ``Http404`` error before redirecting to it::
|
|||
permalink()
|
||||
-----------
|
||||
|
||||
The :func:`django.db.models.permalink` decorator is useful for writing short
|
||||
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.
|
||||
|
||||
|
|
|
@ -421,9 +421,9 @@ options to views.
|
|||
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.
|
||||
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:
|
||||
|
||||
|
@ -510,6 +510,103 @@ imported::
|
|||
(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 and the
|
||||
:func:`django.db.models.permalink` decorator.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Consider again this URLconf entry::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('',
|
||||
#...
|
||||
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('new.views.year_archive', args=(year,)))
|
||||
|
||||
If, for some reason, it was decided that the URL 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 identificator for it when it 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
|
||||
|
@ -689,9 +786,10 @@ URL namespaces and included URLconfs
|
|||
|
||||
URL namespaces of included URLconfs can be specified in two ways.
|
||||
|
||||
Firstly, you can provide the application and :term:`instance namespace` as
|
||||
arguments to :func:`django.conf.urls.include()` when you construct your URL
|
||||
patterns. For example,::
|
||||
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,::
|
||||
|
||||
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
|
||||
|
||||
|
@ -706,6 +804,15 @@ However, you can also ``include()`` a 3-tuple containing::
|
|||
|
||||
(<patterns object>, <application namespace>, <instance namespace>)
|
||||
|
||||
For example::
|
||||
|
||||
help_patterns = patterns('',
|
||||
url(r'^basic/$', 'apps.help.views.views.basic'),
|
||||
url(r'^advanced/$', 'apps.help.views.views.advanced'),
|
||||
)
|
||||
|
||||
(r'^help/', include(help_patterns, 'bar', 'foo')),
|
||||
|
||||
This will include the nominated URL patterns into the given application and
|
||||
instance namespace.
|
||||
|
||||
|
|
|
@ -769,7 +769,7 @@ Use the ``django.test.client.Client`` class to make requests.
|
|||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
If you had an url ``/redirect_me/`` that redirected to ``/next/``, that
|
||||
If you had a URL ``/redirect_me/`` that redirected to ``/next/``, that
|
||||
redirected to ``/final/``, this is what you'd see::
|
||||
|
||||
>>> response = c.get('/redirect_me/', follow=True)
|
||||
|
|
Loading…
Reference in New Issue