Refs #28593 -- Moved django.conf.urls.include() to django.urls().
The old location remains for backwards compatibility. Documentation will be updated separately along with the rest of the URL routing changes.
This commit is contained in:
parent
0214f367bc
commit
ee4043f735
|
@ -1,9 +1,4 @@
|
|||
from importlib import import_module
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.urls import (
|
||||
LocaleRegexURLResolver, RegexURLPattern, RegexURLResolver,
|
||||
)
|
||||
from django.urls import RegexURLPattern, RegexURLResolver, include
|
||||
from django.views import defaults
|
||||
|
||||
__all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url']
|
||||
|
@ -14,54 +9,6 @@ handler404 = defaults.page_not_found
|
|||
handler500 = defaults.server_error
|
||||
|
||||
|
||||
def include(arg, namespace=None):
|
||||
app_name = None
|
||||
if isinstance(arg, tuple):
|
||||
# callable returning a namespace hint
|
||||
try:
|
||||
urlconf_module, app_name = arg
|
||||
except ValueError:
|
||||
if namespace:
|
||||
raise ImproperlyConfigured(
|
||||
'Cannot override the namespace for a dynamic module that '
|
||||
'provides a namespace.'
|
||||
)
|
||||
raise ImproperlyConfigured(
|
||||
'Passing a %d-tuple to django.conf.urls.include() is not supported. '
|
||||
'Pass a 2-tuple containing the list of patterns and app_name, '
|
||||
'and provide the namespace argument to include() instead.' % len(arg)
|
||||
)
|
||||
else:
|
||||
# No namespace hint - use manually provided namespace
|
||||
urlconf_module = arg
|
||||
|
||||
if isinstance(urlconf_module, str):
|
||||
urlconf_module = import_module(urlconf_module)
|
||||
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
|
||||
app_name = getattr(urlconf_module, 'app_name', app_name)
|
||||
if namespace and not app_name:
|
||||
raise ImproperlyConfigured(
|
||||
'Specifying a namespace in django.conf.urls.include() without '
|
||||
'providing an app_name is not supported. Set the app_name attribute '
|
||||
'in the included module, or pass a 2-tuple containing the list of '
|
||||
'patterns and app_name instead.',
|
||||
)
|
||||
|
||||
namespace = namespace or app_name
|
||||
|
||||
# Make sure we can iterate through the patterns (without this, some
|
||||
# testcases will break).
|
||||
if isinstance(patterns, (list, tuple)):
|
||||
for url_pattern in patterns:
|
||||
# Test if the LocaleRegexURLResolver is used within the include;
|
||||
# this should throw an error since this is not allowed!
|
||||
if isinstance(url_pattern, LocaleRegexURLResolver):
|
||||
raise ImproperlyConfigured(
|
||||
'Using i18n_patterns in an included URLconf is not allowed.')
|
||||
|
||||
return (urlconf_module, app_name, namespace)
|
||||
|
||||
|
||||
def url(regex, view, kwargs=None, name=None):
|
||||
if isinstance(view, (list, tuple)):
|
||||
# For include(...) processing.
|
||||
|
|
|
@ -3,6 +3,7 @@ from .base import (
|
|||
is_valid_path, resolve, reverse, reverse_lazy, set_script_prefix,
|
||||
set_urlconf, translate_url,
|
||||
)
|
||||
from .conf import include
|
||||
from .exceptions import NoReverseMatch, Resolver404
|
||||
from .resolvers import (
|
||||
LocaleRegexProvider, LocaleRegexURLResolver, RegexURLPattern,
|
||||
|
@ -15,6 +16,6 @@ __all__ = [
|
|||
'RegexURLPattern', 'RegexURLResolver', 'Resolver404', 'ResolverMatch',
|
||||
'clear_script_prefix', 'clear_url_caches', 'get_callable', 'get_mod_func',
|
||||
'get_ns_resolver', 'get_resolver', 'get_script_prefix', 'get_urlconf',
|
||||
'is_valid_path', 'resolve', 'reverse', 'reverse_lazy', 'set_script_prefix',
|
||||
'set_urlconf', 'translate_url',
|
||||
'include', 'is_valid_path', 'resolve', 'reverse', 'reverse_lazy',
|
||||
'set_script_prefix', 'set_urlconf', 'translate_url',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
"""Functions for use in URLsconfs."""
|
||||
from importlib import import_module
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from .resolvers import LocaleRegexURLResolver
|
||||
|
||||
|
||||
def include(arg, namespace=None):
|
||||
app_name = None
|
||||
if isinstance(arg, tuple):
|
||||
# Callable returning a namespace hint.
|
||||
try:
|
||||
urlconf_module, app_name = arg
|
||||
except ValueError:
|
||||
if namespace:
|
||||
raise ImproperlyConfigured(
|
||||
'Cannot override the namespace for a dynamic module that '
|
||||
'provides a namespace.'
|
||||
)
|
||||
raise ImproperlyConfigured(
|
||||
'Passing a %d-tuple to include() is not supported. Pass a '
|
||||
'2-tuple containing the list of patterns and app_name, and '
|
||||
'provide the namespace argument to include() instead.' % len(arg)
|
||||
)
|
||||
else:
|
||||
# No namespace hint - use manually provided namespace.
|
||||
urlconf_module = arg
|
||||
|
||||
if isinstance(urlconf_module, str):
|
||||
urlconf_module = import_module(urlconf_module)
|
||||
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
|
||||
app_name = getattr(urlconf_module, 'app_name', app_name)
|
||||
if namespace and not app_name:
|
||||
raise ImproperlyConfigured(
|
||||
'Specifying a namespace in include() without providing an app_name '
|
||||
'is not supported. Set the app_name attribute in the included '
|
||||
'module, or pass a 2-tuple containing the list of patterns and '
|
||||
'app_name instead.',
|
||||
)
|
||||
namespace = namespace or app_name
|
||||
# Make sure the patterns can be iterated through (without this, some
|
||||
# testcases will break).
|
||||
if isinstance(patterns, (list, tuple)):
|
||||
for url_pattern in patterns:
|
||||
if isinstance(url_pattern, LocaleRegexURLResolver):
|
||||
raise ImproperlyConfigured(
|
||||
'Using i18n_patterns in an included URLconf is not allowed.'
|
||||
)
|
||||
return (urlconf_module, app_name, namespace)
|
|
@ -1,6 +1,51 @@
|
|||
======================================
|
||||
``django.conf.urls`` utility functions
|
||||
======================================
|
||||
=============================================
|
||||
``django.urls`` functions for use in URLconfs
|
||||
=============================================
|
||||
|
||||
.. module:: django.urls.conf
|
||||
:synopsis: Functions for use in URLconfs.
|
||||
|
||||
.. currentmodule:: django.conf.urls
|
||||
|
||||
``include()``
|
||||
=============
|
||||
|
||||
.. function:: include(module, namespace=None)
|
||||
include(pattern_list)
|
||||
include((pattern_list, app_namespace), namespace=None)
|
||||
|
||||
A function that takes a full Python import path to another URLconf module
|
||||
that should be "included" in this place. Optionally, the :term:`application
|
||||
namespace` and :term:`instance namespace` where the entries will be included
|
||||
into can also be specified.
|
||||
|
||||
Usually, the application namespace should be specified by the included
|
||||
module. If an application namespace is set, the ``namespace`` argument
|
||||
can be used to set a different instance namespace.
|
||||
|
||||
``include()`` also accepts as an argument either an iterable that returns
|
||||
URL patterns or a 2-tuple containing such iterable plus the names of the
|
||||
application namespaces.
|
||||
|
||||
:arg module: URLconf module (or module name)
|
||||
:arg namespace: Instance namespace for the URL entries being included
|
||||
:type namespace: string
|
||||
:arg pattern_list: Iterable of :func:`django.conf.urls.url` instances
|
||||
:arg app_namespace: Application namespace for the URL entries being included
|
||||
:type app_namespace: string
|
||||
:arg instance_namespace: Instance namespace for the URL entries being included
|
||||
:type instance_namespace: string
|
||||
|
||||
See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
In older versions, this function is located in ``django.conf.urls``. The
|
||||
old location still works for backwards compatibility.
|
||||
|
||||
==================================================
|
||||
``django.conf.urls`` functions for use in URLconfs
|
||||
==================================================
|
||||
|
||||
.. module:: django.conf.urls
|
||||
|
||||
|
@ -50,37 +95,6 @@ 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.
|
||||
|
||||
``include()``
|
||||
=============
|
||||
|
||||
.. function:: include(module, namespace=None)
|
||||
include(pattern_list)
|
||||
include((pattern_list, app_namespace), namespace=None)
|
||||
|
||||
A function that takes a full Python import path to another URLconf module
|
||||
that should be "included" in this place. Optionally, the :term:`application
|
||||
namespace` and :term:`instance namespace` where the entries will be included
|
||||
into can also be specified.
|
||||
|
||||
Usually, the application namespace should be specified by the included
|
||||
module. If an application namespace is set, the ``namespace`` argument
|
||||
can be used to set a different instance namespace.
|
||||
|
||||
``include()`` also accepts as an argument either an iterable that returns
|
||||
URL patterns or a 2-tuple containing such iterable plus the names of the
|
||||
application namespaces.
|
||||
|
||||
:arg module: URLconf module (or module name)
|
||||
:arg namespace: Instance namespace for the URL entries being included
|
||||
:type namespace: string
|
||||
:arg pattern_list: Iterable of :func:`django.conf.urls.url` instances
|
||||
:arg app_namespace: Application namespace for the URL entries being included
|
||||
:type app_namespace: string
|
||||
:arg instance_namespace: Instance namespace for the URL entries being included
|
||||
:type instance_namespace: string
|
||||
|
||||
See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`.
|
||||
|
||||
``handler400``
|
||||
==============
|
||||
|
||||
|
|
|
@ -1158,19 +1158,19 @@ class IncludeTests(SimpleTestCase):
|
|||
|
||||
def test_include_namespace(self):
|
||||
msg = (
|
||||
"Specifying a namespace in django.conf.urls.include() without "
|
||||
"providing an app_name is not supported."
|
||||
'Specifying a namespace in include() without providing an '
|
||||
'app_name is not supported.'
|
||||
)
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
include(self.url_patterns, 'namespace')
|
||||
|
||||
def test_include_4_tuple(self):
|
||||
msg = 'Passing a 4-tuple to django.conf.urls.include() is not supported.'
|
||||
msg = 'Passing a 4-tuple to include() is not supported.'
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
include((self.url_patterns, 'app_name', 'namespace', 'blah'))
|
||||
|
||||
def test_include_3_tuple(self):
|
||||
msg = 'Passing a 3-tuple to django.conf.urls.include() is not supported.'
|
||||
msg = 'Passing a 3-tuple to include() is not supported.'
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
include((self.url_patterns, 'app_name', 'namespace'))
|
||||
|
||||
|
|
Loading…
Reference in New Issue