diff --git a/django/conf/project_template/project_name/urls.py b/django/conf/project_template/project_name/urls.py index d85c6f8e28..308d0b4d33 100644 --- a/django/conf/project_template/project_name/urls.py +++ b/django/conf/project_template/project_name/urls.py @@ -1,10 +1,10 @@ -from django.conf.urls import patterns, include, url +from django.conf.urls import include, url from django.contrib import admin -urlpatterns = patterns('', +urlpatterns = [ # Examples: # url(r'^$', '{{ project_name }}.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), -) +] diff --git a/django/conf/urls/__init__.py b/django/conf/urls/__init__.py index 2fe0cf5946..60c767fc9b 100644 --- a/django/conf/urls/__init__.py +++ b/django/conf/urls/__init__.py @@ -1,9 +1,11 @@ from importlib import import_module +import warnings from django.core.urlresolvers import (RegexURLPattern, RegexURLResolver, LocaleRegexURLResolver) from django.core.exceptions import ImproperlyConfigured from django.utils import six +from django.utils.deprecation import RemovedInDjango20Warning __all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'patterns', 'url'] @@ -42,6 +44,12 @@ def include(arg, namespace=None, app_name=None): def patterns(prefix, *args): + warnings.warn( + 'django.conf.urls.patterns() is deprecated and will be removed in ' + 'Django 2.0. Update your urlpatterns to be a list of ' + 'django.conf.urls.url() instances instead.', + RemovedInDjango20Warning, stacklevel=2 + ) pattern_list = [] for t in args: if isinstance(t, (list, tuple)): diff --git a/django/conf/urls/i18n.py b/django/conf/urls/i18n.py index 1b0a1da438..dbddcc0554 100644 --- a/django/conf/urls/i18n.py +++ b/django/conf/urls/i18n.py @@ -1,6 +1,10 @@ +import warnings + from django.conf import settings from django.conf.urls import patterns, url from django.core.urlresolvers import LocaleRegexURLResolver +from django.utils import six +from django.utils.deprecation import RemovedInDjango20Warning def i18n_patterns(prefix, *args): @@ -8,14 +12,23 @@ def i18n_patterns(prefix, *args): Adds the language code prefix to every URL pattern within this function. This may only be used in the root URLconf, not in an included URLconf. - """ - pattern_list = patterns(prefix, *args) + if isinstance(prefix, (six.text_type, str)): + warnings.warn( + "Calling i18n_patterns() with the `prefix` argument and with tuples " + "instead of django.conf.urls.url() instances is deprecated and " + "will no longer work in Django 2.0. Use a list of " + "django.conf.urls.url() instances instead.", + RemovedInDjango20Warning, stacklevel=2 + ) + pattern_list = patterns(prefix, *args) + else: + pattern_list = [prefix] + list(args) if not settings.USE_I18N: return pattern_list return [LocaleRegexURLResolver(pattern_list)] -urlpatterns = patterns('', +urlpatterns = [ url(r'^setlang/$', 'django.views.i18n.set_language', name='set_language'), -) +] diff --git a/django/conf/urls/static.py b/django/conf/urls/static.py index a596bbbb4b..f3470af025 100644 --- a/django/conf/urls/static.py +++ b/django/conf/urls/static.py @@ -1,7 +1,7 @@ import re from django.conf import settings -from django.conf.urls import patterns, url +from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured @@ -12,9 +12,9 @@ def static(prefix, view='django.views.static.serve', **kwargs): from django.conf import settings from django.conf.urls.static import static - urlpatterns = patterns('', + urlpatterns = [ # ... the rest of your URLconf goes here ... - ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) """ # No-op if not in debug mode or an non-local prefix @@ -22,6 +22,6 @@ def static(prefix, view='django.views.static.serve', **kwargs): return [] elif not prefix: raise ImproperlyConfigured("Empty static prefix not permitted") - return patterns('', + return [ url(r'^%s(?P.*)$' % re.escape(prefix.lstrip('/')), view, kwargs=kwargs), - ) + ] diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 99eb79512c..1dfc84df2f 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -543,7 +543,7 @@ class ModelAdmin(BaseModelAdmin): return inline_instances def get_urls(self): - from django.conf.urls import patterns, url + from django.conf.urls import url def wrap(view): def wrapper(*args, **kwargs): @@ -552,13 +552,13 @@ class ModelAdmin(BaseModelAdmin): info = self.model._meta.app_label, self.model._meta.model_name - urlpatterns = patterns('', + urlpatterns = [ url(r'^$', wrap(self.changelist_view), name='%s_%s_changelist' % info), url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info), url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info), url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info), url(r'^(.+)/$', wrap(self.change_view), name='%s_%s_change' % info), - ) + ] return urlpatterns def urls(self): diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 2e1468b87a..8480c08891 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -177,12 +177,12 @@ class AdminSite(object): class MyAdminSite(AdminSite): def get_urls(self): - from django.conf.urls import patterns, url + from django.conf.urls import url urls = super(MyAdminSite, self).get_urls() - urls += patterns('', + urls += [ url(r'^my_view/$', self.admin_view(some_view)) - ) + ] return urls By default, admin_views are marked non-cacheable using the @@ -211,7 +211,7 @@ class AdminSite(object): return update_wrapper(inner, view) def get_urls(self): - from django.conf.urls import patterns, url, include + from django.conf.urls import url, include # Since this module gets imported in the application's root package, # it cannot import models from other applications at the module level, # and django.contrib.contenttypes.views imports ContentType. @@ -226,7 +226,7 @@ class AdminSite(object): return update_wrapper(wrapper, view) # Admin-site-wide views. - urlpatterns = patterns('', + urlpatterns = [ url(r'^$', wrap(self.index), name='index'), url(r'^login/$', self.login, name='login'), url(r'^logout/$', wrap(self.logout), name='logout'), @@ -234,15 +234,15 @@ class AdminSite(object): url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True), name='password_change_done'), url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'), url(r'^r/(?P\d+)/(?P.+)/$', wrap(contenttype_views.shortcut), name='view_on_site'), - ) + ] # Add in each model's views, and create a list of valid URLS for the # app_index valid_app_labels = [] for model, model_admin in six.iteritems(self._registry): - urlpatterns += patterns('', - url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)) - ) + urlpatterns += [ + url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)), + ] if model._meta.app_label not in valid_app_labels: valid_app_labels.append(model._meta.app_label) @@ -250,9 +250,9 @@ class AdminSite(object): # labels for which we need to allow access to the app_index view, if valid_app_labels: regex = r'^(?P' + '|'.join(valid_app_labels) + ')/$' - urlpatterns += patterns('', + urlpatterns += [ url(regex, wrap(self.app_index), name='app_list'), - ) + ] return urlpatterns @property diff --git a/django/contrib/admindocs/urls.py b/django/contrib/admindocs/urls.py index 3dc55657df..e0b2259ef9 100644 --- a/django/contrib/admindocs/urls.py +++ b/django/contrib/admindocs/urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import patterns, url +from django.conf.urls import url from django.contrib.admindocs import views -urlpatterns = patterns('', +urlpatterns = [ url('^$', views.BaseAdminDocsView.as_view(template_name='admin_doc/index.html'), name='django-admindocs-docroot'), @@ -29,4 +29,4 @@ urlpatterns = patterns('', url('^templates/(?P