[1.7.x] Refs #23276: Removed bad examples of passing views as strings to url()
partial backport of a9fd740d22
from master
This commit is contained in:
parent
49419ffd05
commit
8f9dd9f256
|
@ -186,10 +186,12 @@ example above::
|
|||
|
||||
from django.conf.urls import patterns
|
||||
|
||||
from . import views
|
||||
|
||||
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'),
|
||||
(r'^articles/(\d{4})/$', views.year_archive),
|
||||
(r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
|
||||
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', views.article_detail),
|
||||
)
|
||||
|
||||
The code above maps URLs, as simple `regular expressions`_, to the location of
|
||||
|
|
|
@ -2568,10 +2568,12 @@ your URLconf. Specifically, add these four patterns:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
url(r'^admin/password_reset/$', 'django.contrib.auth.views.password_reset', name='admin_password_reset'),
|
||||
url(r'^admin/password_reset/done/$', 'django.contrib.auth.views.password_reset_done', name='password_reset_done'),
|
||||
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', name='password_reset_confirm'),
|
||||
url(r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete', name='password_reset_complete'),
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
||||
url(r'^admin/password_reset/$', auth_views.password_reset, name='admin_password_reset'),
|
||||
url(r'^admin/password_reset/done/$', auth_views.password_reset_done, name='password_reset_done'),
|
||||
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', auth_views.password_reset_confirm, name='password_reset_confirm'),
|
||||
url(r'^reset/done/$', auth_views.password_reset_complete, name='password_reset_complete'),
|
||||
|
||||
.. versionchanged:: 1.6
|
||||
|
||||
|
|
|
@ -54,7 +54,10 @@ 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})
|
||||
from django.contrib.sitemaps.views import sitemap
|
||||
|
||||
(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
|
||||
name='django.contrib.sitemaps.views.sitemap')
|
||||
|
||||
This tells Django to build a sitemap when a client accesses :file:`/sitemap.xml`.
|
||||
|
||||
|
@ -267,6 +270,7 @@ Here's an example of a :doc:`URLconf </topics/http/urls>` using both::
|
|||
|
||||
from django.conf.urls import patterns
|
||||
from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
|
||||
from django.contrib.sitemaps.views import sitemap
|
||||
from blog.models import Entry
|
||||
|
||||
info_dict = {
|
||||
|
@ -284,7 +288,8 @@ Here's an example of a :doc:`URLconf </topics/http/urls>` using both::
|
|||
# ...
|
||||
|
||||
# the sitemap
|
||||
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
|
||||
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
|
||||
name='django.contrib.sitemaps.views.sitemap'),
|
||||
)
|
||||
|
||||
.. _URLconf: ../url_dispatch/
|
||||
|
@ -300,8 +305,11 @@ the sitemap. For example::
|
|||
|
||||
# sitemaps.py
|
||||
from django.contrib import sitemaps
|
||||
from django.contrib.sitemaps.views import sitemap
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from . import views
|
||||
|
||||
class StaticViewSitemap(sitemaps.Sitemap):
|
||||
priority = 0.5
|
||||
changefreq = 'daily'
|
||||
|
@ -321,11 +329,12 @@ the sitemap. For example::
|
|||
}
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'views.main', name='main'),
|
||||
url(r'^about/$', 'views.about', name='about'),
|
||||
url(r'^license/$', 'views.license', name='license'),
|
||||
url(r'^$', views.main, name='main'),
|
||||
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$', sitemap, {'sitemaps': sitemaps},
|
||||
name='django.contrib.sitemaps.views.sitemap')
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -74,11 +74,13 @@ Here's a sample URLconf::
|
|||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
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'),
|
||||
url(r'^articles/2003/$', views.special_case_2003),
|
||||
url(r'^articles/(\d{4})/$', views.year_archive),
|
||||
url(r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
|
||||
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', views.article_detail),
|
||||
)
|
||||
|
||||
Notes:
|
||||
|
@ -96,7 +98,7 @@ 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')``.
|
||||
``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.
|
||||
|
@ -110,7 +112,7 @@ Example requests:
|
|||
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')``.
|
||||
the function ``views.article_detail(request, '2003', '03', '03')``.
|
||||
|
||||
.. _Dive Into Python's explanation: http://www.diveintopython.net/regular_expressions/street_addresses.html#re.matching.2.3
|
||||
|
||||
|
@ -131,11 +133,13 @@ Here's the above example URLconf, rewritten to use named groups::
|
|||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
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'),
|
||||
url(r'^articles/2003/$', views.special_case_2003),
|
||||
url(r'^articles/(?P<year>\d{4})/$', views.year_archive),
|
||||
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.month_archive),
|
||||
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', views.article_detail),
|
||||
)
|
||||
|
||||
This accomplishes exactly the same thing as the previous example, with one
|
||||
|
@ -143,11 +147,11 @@ 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')``.
|
||||
``views.month_archive(request, year='2005', month='03')``, instead
|
||||
of ``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')``.
|
||||
``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'
|
||||
|
@ -191,9 +195,9 @@ 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'),
|
||||
url(r'^articles/(?P<year>\d{4})/$', views.year_archive),
|
||||
|
||||
...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
|
||||
...the ``year`` argument to ``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
|
||||
|
@ -205,9 +209,11 @@ Here's an example URLconf and view::
|
|||
# URLconf
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^blog/$', 'blog.views.page'),
|
||||
url(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
|
||||
url(r'^blog/$', views.page),
|
||||
url(r'^blog/page(?P<num>\d+)/$', views.page),
|
||||
)
|
||||
|
||||
# View (in blog/views.py)
|
||||
|
@ -216,7 +222,7 @@ Here's an example URLconf and view::
|
|||
...
|
||||
|
||||
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
|
||||
``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.
|
||||
|
@ -260,15 +266,67 @@ The variables are:
|
|||
* ``handler403`` -- See :data:`django.conf.urls.handler403`.
|
||||
* ``handler400`` -- See :data:`django.conf.urls.handler400`.
|
||||
|
||||
Passing strings instead of callable objects
|
||||
===========================================
|
||||
|
||||
It is possible to pass a string containing the path to a view rather than the
|
||||
actual Python function object. This alternative is supported for the time
|
||||
being, though is not recommended and will be removed in a future version of
|
||||
Django.
|
||||
|
||||
For example, given this URLconf using Python function objects::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
from mysite.views import archive, about, contact
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^archive/$', archive),
|
||||
url(r'^about/$', about),
|
||||
url(r'^contact/$', contact),
|
||||
)
|
||||
|
||||
You can accomplish the same thing by passing strings rather than objects::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^archive/$', 'mysite.views.archive'),
|
||||
url(r'^about/$', 'mysite.views.about'),
|
||||
url(r'^contact/$', 'mysite.views.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 patterns, url
|
||||
from mysite import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^archive/$', views.archive),
|
||||
url(r'^about/$', views.about),
|
||||
url(r'^contact/$', views.contact),
|
||||
)
|
||||
|
||||
Note that :doc:`class based views</topics/class-based-views/index>` must be
|
||||
imported::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
from mysite.views import ClassBasedView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^myview/$', ClassBasedView.as_view()),
|
||||
)
|
||||
|
||||
.. _urlpatterns-view-prefix:
|
||||
|
||||
The view prefix
|
||||
===============
|
||||
|
||||
You can specify a common prefix in your ``patterns()`` call, to cut down on
|
||||
code duplication.
|
||||
If you do use strings, it is possible to specify a common prefix in your
|
||||
``patterns()`` call.
|
||||
|
||||
Here's the example URLconf from the :doc:`Django overview </intro/overview>`::
|
||||
Here's an example URLconf based on the :doc:`Django overview </intro/overview>`::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
|
@ -283,7 +341,7 @@ 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::
|
||||
With this in mind, the above example can be written as::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
|
@ -361,13 +419,16 @@ instead. For example, consider this URLconf::
|
|||
|
||||
from django.conf.urls import include, patterns, url
|
||||
|
||||
from apps.main import views as main_views
|
||||
from credit import views as credit_views
|
||||
|
||||
extra_patterns = patterns('',
|
||||
url(r'^reports/(?P<id>\d+)/$', 'credit.views.report'),
|
||||
url(r'^charge/$', 'credit.views.charge'),
|
||||
url(r'^reports/(?P<id>\d+)/$', credit_views.report),
|
||||
url(r'^charge/$', credit_views.charge),
|
||||
)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'apps.main.views.homepage'),
|
||||
url(r'^$', main_views.homepage),
|
||||
url(r'^help/', include('apps.help.urls')),
|
||||
url(r'^credit/', include(extra_patterns)),
|
||||
)
|
||||
|
@ -442,13 +503,14 @@ function.
|
|||
For example::
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('blog.views',
|
||||
url(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
|
||||
urlpatterns = patterns('',
|
||||
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')``.
|
||||
``views.year_archive(request, year='2005', foo='bar')``.
|
||||
|
||||
This technique is used in the
|
||||
:doc:`syndication framework </ref/contrib/syndication>` to pass metadata and
|
||||
|
@ -509,62 +571,6 @@ 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 patterns, url
|
||||
|
||||
urlpatterns = patterns('',
|
||||
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 patterns, url
|
||||
from mysite.views import archive, about, contact
|
||||
|
||||
urlpatterns = patterns('',
|
||||
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 patterns, url
|
||||
from mysite import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
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 patterns, url
|
||||
from mysite.views import ClassBasedView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^myview/$', ClassBasedView.as_view()),
|
||||
)
|
||||
|
||||
Reverse resolution of URLs
|
||||
==========================
|
||||
|
@ -621,9 +627,11 @@ Consider again this URLconf entry::
|
|||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
#...
|
||||
url(r'^articles/(\d{4})/$', 'news.views.year_archive'),
|
||||
url(r'^articles/(\d{4})/$', views.year_archive),
|
||||
#...
|
||||
)
|
||||
|
||||
|
@ -870,9 +878,11 @@ For example::
|
|||
|
||||
from django.conf.urls import include, patterns, url
|
||||
|
||||
from app.helps import views
|
||||
|
||||
help_patterns = patterns('',
|
||||
url(r'^basic/$', 'apps.help.views.views.basic'),
|
||||
url(r'^advanced/$', 'apps.help.views.views.advanced'),
|
||||
url(r'^basic/$', views.views.basic),
|
||||
url(r'^advanced/$', views.views.advanced),
|
||||
)
|
||||
|
||||
url(r'^help/', include((help_patterns, 'bar', 'foo'))),
|
||||
|
|
|
@ -1095,18 +1095,22 @@ prepend the current active language code to all url patterns defined within
|
|||
from django.conf.urls import patterns, include, url
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
|
||||
from about import views as about_views
|
||||
from news import views as news_views
|
||||
from sitemap.views import sitemap
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^sitemap\.xml$', 'sitemap.view', name='sitemap_xml'),
|
||||
url(r'^sitemap\.xml$', sitemap, name='sitemap_xml'),
|
||||
)
|
||||
|
||||
news_patterns = patterns('',
|
||||
url(r'^$', 'news.views.index', name='index'),
|
||||
url(r'^category/(?P<slug>[\w-]+)/$', 'news.views.category', name='category'),
|
||||
url(r'^(?P<slug>[\w-]+)/$', 'news.views.details', name='detail'),
|
||||
url(r'^$', news_views.index, name='index'),
|
||||
url(r'^category/(?P<slug>[\w-]+)/$', news_views.category, name='category'),
|
||||
url(r'^(?P<slug>[\w-]+)/$', news_views.details, name='detail'),
|
||||
)
|
||||
|
||||
urlpatterns += i18n_patterns('',
|
||||
url(r'^about/$', 'about.view', name='about'),
|
||||
url(r'^about/$', about_views.main, name='about'),
|
||||
url(r'^news/', include(news_patterns, namespace='news')),
|
||||
)
|
||||
|
||||
|
@ -1150,18 +1154,22 @@ URL patterns can also be marked translatable using the
|
|||
from django.conf.urls.i18n import i18n_patterns
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from about import views as about_views
|
||||
from news import views as news_views
|
||||
from sitemaps.views import sitemap
|
||||
|
||||
urlpatterns = patterns(''
|
||||
url(r'^sitemap\.xml$', 'sitemap.view', name='sitemap_xml'),
|
||||
url(r'^sitemap\.xml$', sitemap, name='sitemap_xml'),
|
||||
)
|
||||
|
||||
news_patterns = patterns(''
|
||||
url(r'^$', 'news.views.index', name='index'),
|
||||
url(_(r'^category/(?P<slug>[\w-]+)/$'), 'news.views.category', name='category'),
|
||||
url(r'^(?P<slug>[\w-]+)/$', 'news.views.details', name='detail'),
|
||||
url(r'^$', news_views.index, name='index'),
|
||||
url(_(r'^category/(?P<slug>[\w-]+)/$'), news_views.category, name='category'),
|
||||
url(r'^(?P<slug>[\w-]+)/$', news_views.details, name='detail'),
|
||||
)
|
||||
|
||||
urlpatterns += i18n_patterns('',
|
||||
url(_(r'^about/$'), 'about.view', name='about'),
|
||||
url(_(r'^about/$'), about_views.main, name='about'),
|
||||
url(_(r'^news/'), include(news_patterns, namespace='news')),
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue