Fixed #23276 -- Deprecated passing views as strings to url().

This commit is contained in:
Tim Graham 2014-08-12 10:54:42 -04:00
parent 2003cb23d4
commit a9fd740d22
28 changed files with 207 additions and 182 deletions

View File

@ -67,6 +67,12 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
else:
if isinstance(view, six.string_types):
warnings.warn(
'Support for string view arguments to url() is deprecated and '
'will be removed in Django 2.0 (got %s). Pass the callable '
'instead.' % view,
RemovedInDjango20Warning, stacklevel=2
)
if not view:
raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
if prefix:

View File

@ -5,6 +5,7 @@ from django.conf.urls import patterns, url
from django.core.urlresolvers import LocaleRegexURLResolver
from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning
from django.views.i18n import set_language
def i18n_patterns(prefix, *args):
@ -30,5 +31,5 @@ def i18n_patterns(prefix, *args):
urlpatterns = [
url(r'^setlang/$', 'django.views.i18n.set_language', name='set_language'),
url(r'^setlang/$', set_language, name='set_language'),
]

View File

@ -3,9 +3,10 @@ import re
from django.conf import settings
from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured
from django.views.static import serve
def static(prefix, view='django.views.static.serve', **kwargs):
def static(prefix, view=serve, **kwargs):
"""
Helper function to return a URL pattern for serving files in debug mode.

View File

@ -3,7 +3,7 @@ from django.contrib import admin
from django.contrib.auth import context_processors
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.urls import urlpatterns
from django.contrib.auth.views import password_reset, login
from django.contrib.auth import views
from django.contrib.auth.decorators import login_required
from django.contrib.messages.api import info
from django.http import HttpResponse, HttpRequest
@ -67,29 +67,29 @@ def userpage(request):
def custom_request_auth_login(request):
return login(request, authentication_form=CustomRequestAuthenticationForm)
return views.login(request, authentication_form=CustomRequestAuthenticationForm)
# special urls for auth test cases
urlpatterns += [
url(r'^logout/custom_query/$', 'django.contrib.auth.views.logout', dict(redirect_field_name='follow')),
url(r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')),
url(r'^logout/next_page/named/$', 'django.contrib.auth.views.logout', dict(next_page='password_reset')),
url(r'^logout/custom_query/$', views.logout, dict(redirect_field_name='follow')),
url(r'^logout/next_page/$', views.logout, dict(next_page='/somewhere/')),
url(r'^logout/next_page/named/$', views.logout, dict(next_page='password_reset')),
url(r'^remote_user/$', remote_user_auth_view),
url(r'^password_reset_from_email/$', 'django.contrib.auth.views.password_reset', dict(from_email='staffmember@example.com')),
url(r'^password_reset/custom_redirect/$', 'django.contrib.auth.views.password_reset', dict(post_reset_redirect='/custom/')),
url(r'^password_reset/custom_redirect/named/$', 'django.contrib.auth.views.password_reset', dict(post_reset_redirect='password_reset')),
url(r'^password_reset/html_email_template/$', 'django.contrib.auth.views.password_reset', dict(html_email_template_name='registration/html_password_reset_email.html')),
url(r'^password_reset_from_email/$', views.password_reset, dict(from_email='staffmember@example.com')),
url(r'^password_reset/custom_redirect/$', views.password_reset, dict(post_reset_redirect='/custom/')),
url(r'^password_reset/custom_redirect/named/$', views.password_reset, dict(post_reset_redirect='password_reset')),
url(r'^password_reset/html_email_template/$', views.password_reset, dict(html_email_template_name='registration/html_password_reset_email.html')),
url(r'^reset/custom/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
views.password_reset_confirm,
dict(post_reset_redirect='/custom/')),
url(r'^reset/custom/named/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
views.password_reset_confirm,
dict(post_reset_redirect='password_reset')),
url(r'^password_change/custom/$', 'django.contrib.auth.views.password_change', dict(post_change_redirect='/custom/')),
url(r'^password_change/custom/named/$', 'django.contrib.auth.views.password_change', dict(post_change_redirect='password_reset')),
url(r'^admin_password_reset/$', 'django.contrib.auth.views.password_reset', dict(is_admin_site=True)),
url(r'^login_required/$', login_required(password_reset)),
url(r'^login_required_login_url/$', login_required(password_reset, login_url='/somewhere/')),
url(r'^password_change/custom/$', views.password_change, dict(post_change_redirect='/custom/')),
url(r'^password_change/custom/named/$', views.password_change, dict(post_change_redirect='password_reset')),
url(r'^admin_password_reset/$', views.password_reset, dict(is_admin_site=True)),
url(r'^login_required/$', login_required(views.password_reset)),
url(r'^login_required_login_url/$', login_required(views.password_reset, login_url='/somewhere/')),
url(r'^auth_processor_no_attr_access/$', auth_processor_no_attr_access),
url(r'^auth_processor_attr_access/$', auth_processor_attr_access),

View File

@ -1,5 +1,6 @@
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.views import serve
urlpatterns = []
@ -10,7 +11,7 @@ def staticfiles_urlpatterns(prefix=None):
"""
if prefix is None:
prefix = settings.STATIC_URL
return static(prefix, view='django.contrib.staticfiles.views.serve')
return static(prefix, view=serve)
# Only append if urlpatterns are empty
if settings.DEBUG and not urlpatterns:

View File

@ -21,7 +21,9 @@ def serve(request, path, insecure=False, **kwargs):
To use, put a URL pattern such as::
(r'^(?P<path>.*)$', 'django.contrib.staticfiles.views.serve')
from django.contrib.staticfiles import views
url(r'^(?P<path>.*)$', views.serve)
in your URLconf.

View File

@ -24,7 +24,9 @@ def serve(request, path, document_root=None, show_indexes=False):
To use, put a URL pattern such as::
(r'^(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/my/files/'})
from django.views.static import serve
url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'})
in your URLconf. You must provide the ``document_root`` param. You may
also set ``show_indexes`` to ``True`` if you'd like to serve a basic index

View File

@ -44,6 +44,8 @@ about each item can often be found in the release notes of two versions prior.
* The ``unordered_list`` filter will no longer support old style lists.
* Support for string ``view`` arguments to ``url()`` will be removed.
.. _deprecation-removed-in-1.9:
1.9

View File

@ -186,10 +186,12 @@ example above::
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
The code above maps URLs, as simple `regular expressions`_, to the location of

View File

@ -2571,10 +2571,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'),
(This assumes you've added the admin at ``admin/`` and requires that you put
the URLs starting with ``^admin/`` before the line that includes the admin app

View File

@ -54,8 +54,10 @@ Initialization
To activate sitemap generation on your Django site, add this line to your
:doc:`URLconf </topics/http/urls>`::
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')
from django.contrib.sitemaps.views import sitemap
url(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`.
@ -277,6 +279,7 @@ Here's an example of a :doc:`URLconf </topics/http/urls>` using both::
from django.conf.urls import url
from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
from django.contrib.sitemaps.views import sitemap
from blog.models import Entry
info_dict = {
@ -294,8 +297,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}, name='django.contrib.sitemaps.views.sitemap'),
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
]
.. _URLconf: ../url_dispatch/
@ -311,8 +314,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'
@ -332,12 +338,12 @@ the sitemap. For example::
}
urlpatterns = [
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}, name='django.contrib.sitemaps.views.sitemap')
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
]

View File

@ -78,7 +78,7 @@ The ``optional_dictionary`` and ``optional_name`` parameters are described in
static()
--------
.. function:: static.static(prefix, view='django.views.static.serve', **kwargs)
.. function:: static.static(prefix, view=django.views.static.serve, **kwargs)
Helper function to return a URL pattern for serving files in debug mode::
@ -89,6 +89,11 @@ Helper function to return a URL pattern for serving files in debug mode::
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
.. versionchanged:: 1.8
The ``view`` argument changed from a string
(``'django.views.static.serve'``) to the function.
url()
-----
@ -111,9 +116,14 @@ function or method. See :ref:`views-extra-options` for an example.
See :ref:`Naming URL patterns <naming-url-patterns>` for why the ``name``
parameter is useful.
The ``prefix`` parameter has the same meaning as the first argument to
``patterns()`` and is only relevant when you're passing a string as the
``view`` parameter.
.. deprecated:: 1.8
Support for string ``view`` arguments is deprecated and will be removed in
Django 2.0. Pass the callable instead.
The ``prefix`` parameter has the same meaning as the first argument to
``patterns()`` and is only relevant when you're passing a string as the
``view`` parameter.
include()
---------

View File

@ -548,6 +548,13 @@ Updating your code is as simple as ensuring that ``urlpatterns`` is a list of
url('^other/$', views.otherview),
]
Passing a string as ``view`` to :func:`~django.conf.urls.url`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Related to the previous item, referencing views as strings in the ``url()``
function is deprecated. Pass the callable view as described in the previous
section instead.
``django.test.SimpleTestCase.urls``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -580,8 +587,10 @@ 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')
from django.contrib.sitemaps.views import sitemap
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
to ensure compatibility when reversing by Python path is removed in Django 2.0.

View File

@ -74,11 +74,13 @@ Here's a sample URLconf::
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', 'news.views.special_case_2003'),
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 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 url
from . import views
urlpatterns = [
url(r'^articles/2003/$', 'news.views.special_case_2003'),
url(r'^articles/(?P<year>[0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', 'news.views.article_detail'),
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{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>[0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/(?P<year>[0-9]{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 ``[0-9]{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 url
from . import views
urlpatterns = [
url(r'^blog/$', 'blog.views.page'),
url(r'^blog/page(?P<num>[0-9]+)/$', 'blog.views.page'),
url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>[0-9]+)/$', 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.
@ -290,13 +296,16 @@ Another possibility is to include additional URL patterns by using a list of
from django.conf.urls import include, url
from apps.main import views as main_views
from credit import views as credit_views
extra_patterns = [
url(r'^reports/(?P<id>[0-9]+)/$', 'credit.views.report'),
url(r'^charge/$', 'credit.views.charge'),
url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
url(r'^charge/$', credit_views.charge),
]
urlpatterns = [
url(r'^$', 'apps.main.views.homepage'),
url(r'^$', main_views.homepage),
url(r'^help/', include('apps.help.urls')),
url(r'^credit/', include(extra_patterns)),
]
@ -381,7 +390,7 @@ For example::
]
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
@ -444,60 +453,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 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 :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
==========================
@ -553,9 +508,11 @@ Consider again this URLconf entry::
from django.conf.urls import url
from . import views
urlpatterns = [
#...
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive', name='news-year-archive'),
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
#...
]
@ -756,9 +713,11 @@ For example::
from django.conf.urls import include, url
from app.helps import views
help_patterns = [
url(r'^basic/$', 'apps.help.views.views.basic'),
url(r'^advanced/$', 'apps.help.views.views.advanced'),
url(r'^basic/$', views.basic),
url(r'^advanced/$', views.advanced),
]
url(r'^help/', include((help_patterns, 'bar', 'foo'))),

View File

@ -1100,22 +1100,25 @@ prepend the current active language code to all url patterns defined within
from django.conf.urls import 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 imort sitemap
urlpatterns = [
url(r'^sitemap\.xml$', 'sitemap.view', name='sitemap_xml'),
url(r'^sitemap\.xml$', sitemap, name='sitemap_xml'),
]
news_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')),
)
After defining these URL patterns, Django will automatically add the
language prefix to the URL patterns that were added by the ``i18n_patterns``
function. Example::
@ -1155,22 +1158,25 @@ 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 = [
url(r'^sitemap\.xml$', 'sitemap.view', name='sitemap_xml'),
url(r'^sitemap\.xml$', sitemap, name='sitemap_xml'),
]
news_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')),
)
After you've created the translations, the
:func:`~django.core.urlresolvers.reverse` function will return the URL in the
active language. Example::

View File

@ -1,10 +1,11 @@
import os
from django.conf.urls import url
from django.utils._os import upath
from django.views.static import serve
here = os.path.dirname(upath(__file__))
urlpatterns = [
url(r'^custom_templates/(?P<path>.*)$', 'django.views.static.serve', {
url(r'^custom_templates/(?P<path>.*)$', serve, {
'document_root': os.path.join(here, 'custom_templates')}),
]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from django.views.decorators.cache import cache_page
from django.views.generic import TemplateView
@ -257,5 +258,5 @@ urlpatterns = [
views.BookSigningDetail.as_view()),
# Useful for testing redirects
url(r'^accounts/login/$', 'django.contrib.auth.views.login')
url(r'^accounts/login/$', auth_views.login)
]

View File

@ -1,7 +1,9 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^customurlconf/noslash$', 'middleware.views.empty_view'),
url(r'^customurlconf/slash/$', 'middleware.views.empty_view'),
url(r'^customurlconf/needsquoting#/$', 'middleware.views.empty_view'),
url(r'^customurlconf/noslash$', views.empty_view),
url(r'^customurlconf/slash/$', views.empty_view),
url(r'^customurlconf/needsquoting#/$', views.empty_view),
]

View File

@ -1,7 +1,9 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^noslash$', 'middleware.views.empty_view'),
url(r'^slash/$', 'middleware.views.empty_view'),
url(r'^needsquoting#/$', 'middleware.views.empty_view'),
url(r'^noslash$', views.empty_view),
url(r'^slash/$', views.empty_view),
url(r'^needsquoting#/$', views.empty_view),
]

View File

@ -1,5 +1,7 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^guitarists/(\w{1,50})/$', 'model_permalink.views.empty_view', name='guitarist_detail'),
url(r'^guitarists/(\w{1,50})/$', views.empty_view, name='guitarist_detail'),
]

View File

@ -15,5 +15,5 @@ urlpatterns = [
# Unicode strings are permitted everywhere.
url(r'^Юникод/(\w+)/$', views.client2, name="метка_оператора"),
url(r'^Юникод/(?P<tag>\S+)/$', 'template_tests.views.client2', name="метка_оператора_2"),
url(r'^Юникод/(?P<tag>\S+)/$', views.client2, name="метка_оператора_2"),
]

View File

@ -1,4 +1,5 @@
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from django.views.generic import RedirectView
from . import views
@ -32,6 +33,6 @@ urlpatterns = [
url(r'^mass_mail_sending_view/$', views.mass_mail_sending_view),
url(r'^django_project_redirect/$', views.django_project_redirect),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout'),
url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}),
url(r'^accounts/logout/$', auth_views.logout),
]

View File

@ -1,26 +1,27 @@
import warnings
from django.conf.urls import url
from . import views
urlpatterns = [
# View has erroneous import
url(r'erroneous_inner/$', views.erroneous_view),
# Module has erroneous import
# Remove in Django 2.0 along with erroneous_views_module as this is only
# an issue with string in urlpatterns
url(r'erroneous_outer/$', 'urlpatterns_reverse.erroneous_views_module.erroneous_view'),
# Module is an unqualified string
url(r'erroneous_unqualified/$', 'unqualified_view'),
# View does not exist
# Remove in Django 2.0 along with erroneous_views_module as this is only
# an issue with string in urlpatterns
url(r'missing_inner/$', 'urlpatterns_reverse.views.missing_view'),
# View is not callable
# Remove in Django 2.0 along with erroneous_views_module as this is only
# an issue with string in urlpatterns
url(r'uncallable/$', 'urlpatterns_reverse.views.uncallable'),
# Module does not exist
url(r'missing_outer/$', 'urlpatterns_reverse.missing_module.missing_view'),
# Regex contains an error (refs #6170)
url(r'(regex_error/$', views.empty_view),
]
# Test deprecated behavior of passing strings as view to url().
# Some of these can be removed in Django 2.0 as they aren't convertable to
# callabls.
with warnings.catch_warnings(record=True):
warnings.filterwarnings('ignore', module='django.conf.urls')
urlpatterns = [
# View has erroneous import
url(r'erroneous_inner/$', views.erroneous_view),
# Module has erroneous import
url(r'erroneous_outer/$', 'urlpatterns_reverse.erroneous_views_module.erroneous_view'),
# Module is an unqualified string
url(r'erroneous_unqualified/$', 'unqualified_view'),
# View does not exist
url(r'missing_inner/$', 'urlpatterns_reverse.views.missing_view'),
# View is not callable
url(r'uncallable/$', 'urlpatterns_reverse.views.uncallable'),
# Module does not exist
url(r'missing_outer/$', 'urlpatterns_reverse.missing_module.missing_view'),
# Regex contains an error (refs #6170)
url(r'(regex_error/$', views.empty_view),
]

View File

@ -10,9 +10,9 @@ class URLObject(object):
def urls(self):
return ([
url(r'^inner/$', 'urlpatterns_reverse.views.empty_view', name='urlobject-view'),
url(r'^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', 'urlpatterns_reverse.views.empty_view', name='urlobject-view'),
url(r'^inner/\+\\\$\*/$', 'urlpatterns_reverse.views.empty_view', name='urlobject-special-view'),
url(r'^inner/$', views.empty_view, name='urlobject-view'),
url(r'^inner/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='urlobject-view'),
url(r'^inner/\+\\\$\*/$', views.empty_view, name='urlobject-special-view'),
], self.app_name, self.namespace)
urls = property(urls)

View File

@ -2,12 +2,15 @@ import warnings
from django.conf.urls import patterns, url, include
from .views import empty_view, empty_view_partial, empty_view_wrapped, absolute_kwargs_view
from .views import (
absolute_kwargs_view, defaults_view, empty_view, empty_view_partial,
empty_view_wrapped, nested_view,
)
other_patterns = [
url(r'non_path_include/$', empty_view, name='non_path_include'),
url(r'nested_path/$', 'urlpatterns_reverse.views.nested_view'),
url(r'nested_path/$', nested_view),
]
# test deprecated patterns() function. convert to list of urls() in Django 2.0
@ -68,8 +71,8 @@ with warnings.catch_warnings(record=True):
url(r'absolute_arg_view/$', absolute_kwargs_view),
# Tests for #13154. Mixed syntax to test both ways of defining URLs.
url(r'defaults_view1/(?P<arg1>[0-9]+)/', 'urlpatterns_reverse.views.defaults_view', {'arg2': 1}, name='defaults'),
(r'defaults_view2/(?P<arg1>[0-9]+)/', 'urlpatterns_reverse.views.defaults_view', {'arg2': 2}, 'defaults'),
url(r'defaults_view1/(?P<arg1>[0-9]+)/', defaults_view, {'arg2': 1}, name='defaults'),
(r'defaults_view2/(?P<arg1>[0-9]+)/', defaults_view, {'arg2': 2}, 'defaults'),
url('^includes/', include(other_patterns)),
)

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from django.views.generic import RedirectView
from .models import Article, DateArticle
@ -27,12 +28,12 @@ numeric_days_info_dict = dict(date_based_info_dict, day_format='%d')
date_based_datefield_info_dict = dict(date_based_info_dict, queryset=DateArticle.objects.all())
urlpatterns = [
url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout'),
url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}),
url(r'^accounts/logout/$', auth_views.logout),
# Special URLs for particular regression cases.
url('^中文/$', 'view_tests.views.redirect'),
url('^中文/target/$', 'view_tests.views.index_page'),
url('^中文/$', views.redirect),
url('^中文/target/$', views.index_page),
]
# redirects, both temporary and permanent, with non-ASCII targets

View File

@ -1,5 +1,7 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^index/$', 'view_tests.views.index_page', name='index'),
url(r'^index/$', views.index_page, name='index'),
]

View File

@ -3,7 +3,7 @@ from os import path
from django.conf.urls import url, include
from django.utils._os import upath
from django.views import defaults, i18n
from django.views import defaults, i18n, static
from . import views
@ -71,7 +71,7 @@ urlpatterns = [
url(r'^jsi18n_template/$', views.jsi18n),
# Static views
url(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': media_dir}),
url(r'^site_media/(?P<path>.*)$', static.serve, {'document_root': media_dir}),
]
urlpatterns += [