From 4445d36d471aae81086ed785536687a92e5aaa6d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 3 Jun 2014 07:30:14 -0400 Subject: Fixed #22384 -- Deprecated reversing URLs by dotted path. --- docs/internals/deprecation.txt | 3 ++ docs/ref/contrib/sitemaps.txt | 9 +++-- docs/ref/templates/builtins.txt | 19 +++++++---- docs/ref/urlresolvers.txt | 11 +++--- docs/releases/1.8.txt | 18 ++++++++++ docs/topics/http/urls.txt | 76 ++++++++--------------------------------- 6 files changed, 62 insertions(+), 74 deletions(-) (limited to 'docs') diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 9ccbf440c4..3cbd1e3173 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -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 diff --git a/docs/ref/contrib/sitemaps.txt b/docs/ref/contrib/sitemaps.txt index 12ed61b97a..8c48651054 100644 --- a/docs/ref/contrib/sitemaps.txt +++ b/docs/ref/contrib/sitemaps.txt @@ -54,7 +54,8 @@ Initialization To activate sitemap generation on your Django site, add this line to your :doc:`URLconf `:: - (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 ` 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') ] diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 0e1266e0fb..9d4093e4da 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -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 %} I'm linking to {{ the_url }} @@ -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 %} Link to optional stuff {% endif %} @@ -1051,6 +1051,13 @@ This will follow the normal :ref:`namespaced URL resolution strategy `, 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, diff --git a/docs/ref/urlresolvers.txt b/docs/ref/urlresolvers.txt index 491c4cd14e..79c219a8d8 100644 --- a/docs/ref/urlresolvers.txt +++ b/docs/ref/urlresolvers.txt @@ -16,12 +16,11 @@ your code, Django provides the following function: :ref:`URL pattern name `, or the callable view object. For example, given the following ``url``:: - url(r'^archive/$', 'news.views.archive', name='news_archive') + from news import views -you can use any of the following to reverse the URL:: + url(r'^archive/$', views.archive, name='news_archive') - # using the Python path - reverse('news.views.archive') +you can use any of the following to reverse the URL:: # 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. diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index f716c995ca..0852acb399 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -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 ` +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 diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt index 3833021956..39c96b2e02 100644 --- a/docs/topics/http/urls.txt +++ b/docs/topics/http/urls.txt @@ -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 - 2012 Archive + 2012 Archive {# Or with the year in a template context variable: #} @@ -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:: - - from django.conf.urls import url - from mysite.views import archive - - 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:: +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. - 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. +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: -- cgit v1.3