mirror of
https://github.com/django/django.git
synced 2025-07-24 13:44:32 +00:00
Fixed #22384 -- Deprecated reversing URLs by dotted path.
This commit is contained in:
parent
e020894470
commit
4445d36d47
16 changed files with 134 additions and 114 deletions
|
@ -32,6 +32,9 @@ about each item can often be found in the release notes of two versions prior.
|
|||
and migrations will become compulsory for all apps. This includes automatic
|
||||
loading of fixtures and support for initial SQL data.
|
||||
|
||||
* The ability to :func:`~django.core.urlresolvers.reverse` URLs using a dotted
|
||||
Python path will be removed.
|
||||
|
||||
.. _deprecation-removed-in-1.9:
|
||||
|
||||
1.9
|
||||
|
|
|
@ -54,7 +54,8 @@ Initialization
|
|||
To activate sitemap generation on your Django site, add this line to your
|
||||
:doc:`URLconf </topics/http/urls>`::
|
||||
|
||||
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
|
||||
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
|
||||
|
||||
This tells Django to build a sitemap when a client accesses :file:`/sitemap.xml`.
|
||||
|
||||
|
@ -284,7 +285,8 @@ Here's an example of a :doc:`URLconf </topics/http/urls>` using both::
|
|||
# ...
|
||||
|
||||
# the sitemap
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
|
||||
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
|
||||
]
|
||||
|
||||
.. _URLconf: ../url_dispatch/
|
||||
|
@ -325,7 +327,8 @@ the sitemap. For example::
|
|||
url(r'^about/$', 'views.about', name='about'),
|
||||
url(r'^license/$', 'views.license', name='license'),
|
||||
# ...
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
|
||||
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -982,7 +982,7 @@ resulting path will be encoded using :func:`~django.utils.encoding.iri_to_uri`.
|
|||
This is a way to output links without violating the DRY principle by having to
|
||||
hard-code URLs in your templates::
|
||||
|
||||
{% url 'path.to.some_view' v1 v2 %}
|
||||
{% url 'some-url-name' v1 v2 %}
|
||||
|
||||
The first argument is a path to a view function in the format
|
||||
``package.package.module.function``. It can be a quoted literal or any other
|
||||
|
@ -991,7 +991,7 @@ should be space-separated values that will be used as arguments in the URL.
|
|||
The example above shows passing positional arguments. Alternatively you may
|
||||
use keyword syntax::
|
||||
|
||||
{% url 'path.to.some_view' arg1=v1 arg2=v2 %}
|
||||
{% url 'some-url-name' arg1=v1 arg2=v2 %}
|
||||
|
||||
Do not mix both positional and keyword syntax in a single call. All arguments
|
||||
required by the URLconf should be present.
|
||||
|
@ -1002,7 +1002,7 @@ takes a client ID (here, ``client()`` is a method inside the views file
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
('^client/([0-9]+)/$', 'app_views.client')
|
||||
('^client/([0-9]+)/$', 'app_views.client', name='app-views-client')
|
||||
|
||||
If this app's URLconf is included into the project's URLconf under a path
|
||||
such as this:
|
||||
|
@ -1013,7 +1013,7 @@ such as this:
|
|||
|
||||
...then, in a template, you can create a link to this view like this::
|
||||
|
||||
{% url 'app_views.client' client.id %}
|
||||
{% url 'app-views-client' client.id %}
|
||||
|
||||
The template tag will output the string ``/clients/client/123/``.
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ cause your site to display an error page.
|
|||
If you'd like to retrieve a URL without displaying it, you can use a slightly
|
||||
different call::
|
||||
|
||||
{% url 'path.to.view' arg arg2 as the_url %}
|
||||
{% url 'some-url-name' arg arg2 as the_url %}
|
||||
|
||||
<a href="{{ the_url }}">I'm linking to {{ the_url }}</a>
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ The scope of the variable created by the ``as var`` syntax is the
|
|||
This ``{% url ... as var %}`` syntax will *not* cause an error if the view is
|
||||
missing. In practice you'll use this to link to views that are optional::
|
||||
|
||||
{% url 'path.to.view' as the_url %}
|
||||
{% url 'some-url-name' as the_url %}
|
||||
{% if the_url %}
|
||||
<a href="{{ the_url }}">Link to optional stuff</a>
|
||||
{% endif %}
|
||||
|
@ -1051,6 +1051,13 @@ This will follow the normal :ref:`namespaced URL resolution strategy
|
|||
<topics-http-reversing-url-namespaces>`, including using any hints provided
|
||||
by the context as to the current application.
|
||||
|
||||
.. deprecated:: 1.8
|
||||
|
||||
The dotted Python path syntax is deprecated and will be removed in
|
||||
Django 2.0::
|
||||
|
||||
{% url 'path.to.some_view' v1 v2 %}
|
||||
|
||||
.. warning::
|
||||
|
||||
Don't forget to put quotes around the function path or pattern name,
|
||||
|
|
|
@ -16,13 +16,12 @@ your code, Django provides the following function:
|
|||
:ref:`URL pattern name <naming-url-patterns>`, or the callable view object.
|
||||
For example, given the following ``url``::
|
||||
|
||||
url(r'^archive/$', 'news.views.archive', name='news_archive')
|
||||
from news import views
|
||||
|
||||
url(r'^archive/$', views.archive, name='news_archive')
|
||||
|
||||
you can use any of the following to reverse the URL::
|
||||
|
||||
# using the Python path
|
||||
reverse('news.views.archive')
|
||||
|
||||
# using the named URL
|
||||
reverse('news_archive')
|
||||
|
||||
|
@ -63,6 +62,10 @@ namespaces into URLs on specific application instances, according to the
|
|||
The ``urlconf`` argument is the URLconf module containing the url patterns to
|
||||
use for reversing. By default, the root URLconf for the current thread is used.
|
||||
|
||||
.. deprecated:: 1.8
|
||||
|
||||
The ability to reverse using the Python path, e.g.
|
||||
``reverse('news.views.archive')``, has been deprecated.
|
||||
|
||||
.. admonition:: Make sure your views are all correct.
|
||||
|
||||
|
|
|
@ -323,3 +323,21 @@ Using an incorrect count of unpacked values in the :ttag:`for` template tag
|
|||
|
||||
Using an incorrect count of unpacked values in :ttag:`for` tag will raise an
|
||||
exception rather than fail silently in Django 2.0.
|
||||
|
||||
Passing a dotted path to :func:`~django.core.urlresolvers.reverse()` and :ttag:`url`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reversing URLs by Python path is an expensive operation as it causes the
|
||||
path being reversed to be imported. This behavior has also resulted in a
|
||||
`security issue`_. Use :ref:`named URL patterns <naming-url-patterns>`
|
||||
for reversing instead.
|
||||
|
||||
If you are using :mod:`django.contrib.sitemaps`, add the ``name`` argument to
|
||||
the ``url`` that references :func:`django.contrib.sitemaps.views.sitemap`:
|
||||
|
||||
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
|
||||
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
|
||||
|
||||
to ensure compatibility when reversing by Python path is removed in Django 2.0.
|
||||
|
||||
.. _security issue: https://www.djangoproject.com/weblog/2014/apr/21/security/#s-issue-unexpected-code-execution-using-reverse
|
||||
|
|
|
@ -555,7 +555,7 @@ Consider again this URLconf entry::
|
|||
|
||||
urlpatterns = [
|
||||
#...
|
||||
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
|
||||
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive', name='news-year-archive'),
|
||||
#...
|
||||
]
|
||||
|
||||
|
@ -566,11 +566,11 @@ You can obtain these in template code by using:
|
|||
|
||||
.. code-block:: html+django
|
||||
|
||||
<a href="{% url 'news.views.year_archive' 2012 %}">2012 Archive</a>
|
||||
<a href="{% url 'news-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>
|
||||
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
@ -583,7 +583,7 @@ Or in Python code::
|
|||
# ...
|
||||
year = 2006
|
||||
# ...
|
||||
return HttpResponseRedirect(reverse('news.views.year_archive', args=(year,)))
|
||||
return HttpResponseRedirect(reverse('news-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
|
||||
|
@ -599,65 +599,19 @@ URLs. Read the next section to know about the solution Django provides for this.
|
|||
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::
|
||||
In order to perform URL reversing, you'll need to use **named URL patterns**
|
||||
as done in the examples above. The string used for the URL name can contain any
|
||||
characters you like. You are not restricted to valid Python names.
|
||||
|
||||
from django.conf.urls import url
|
||||
from mysite.views import archive
|
||||
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.
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^archive/([0-9]{4})/$', archive),
|
||||
url(r'^archive-summary/([0-9]{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/([0-9]{4})/$', archive, name="full-archive"),
|
||||
url(r'^archive-summary/([0-9]{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``.
|
||||
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:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue