Refs #21927 -- Removed include()'s app_name argument per deprecation timeline.
Also removed support for passing a 3-tuple to include() and support for setting an instance namespace without an application namespace. Thanks Marten Kenbeek for completing the patch.
This commit is contained in:
parent
c6de8cca20
commit
ad393beeb7
|
@ -1,4 +1,3 @@
|
||||||
import warnings
|
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
@ -6,7 +5,6 @@ from django.urls import (
|
||||||
LocaleRegexURLResolver, RegexURLPattern, RegexURLResolver,
|
LocaleRegexURLResolver, RegexURLPattern, RegexURLResolver,
|
||||||
)
|
)
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
|
||||||
|
|
||||||
__all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url']
|
__all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url']
|
||||||
|
|
||||||
|
@ -16,16 +14,8 @@ handler404 = 'django.views.defaults.page_not_found'
|
||||||
handler500 = 'django.views.defaults.server_error'
|
handler500 = 'django.views.defaults.server_error'
|
||||||
|
|
||||||
|
|
||||||
def include(arg, namespace=None, app_name=None):
|
def include(arg, namespace=None):
|
||||||
if app_name and not namespace:
|
app_name = None
|
||||||
raise ValueError('Must specify a namespace if specifying app_name.')
|
|
||||||
if app_name:
|
|
||||||
warnings.warn(
|
|
||||||
'The app_name argument to django.conf.urls.include() is deprecated. '
|
|
||||||
'Set the app_name in the included URLconf instead.',
|
|
||||||
RemovedInDjango20Warning, stacklevel=2
|
|
||||||
)
|
|
||||||
|
|
||||||
if isinstance(arg, tuple):
|
if isinstance(arg, tuple):
|
||||||
# callable returning a namespace hint
|
# callable returning a namespace hint
|
||||||
try:
|
try:
|
||||||
|
@ -35,13 +25,11 @@ def include(arg, namespace=None, app_name=None):
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
'Cannot override the namespace for a dynamic module that provides a namespace'
|
'Cannot override the namespace for a dynamic module that provides a namespace'
|
||||||
)
|
)
|
||||||
warnings.warn(
|
raise ImproperlyConfigured(
|
||||||
'Passing a 3-tuple to django.conf.urls.include() is deprecated. '
|
'Passing a 3-tuple to django.conf.urls.include() is not supported. '
|
||||||
'Pass a 2-tuple containing the list of patterns and app_name, '
|
'Pass a 2-tuple containing the list of patterns and app_name, '
|
||||||
'and provide the namespace argument to include() instead.',
|
'and provide the namespace argument to include() instead.',
|
||||||
RemovedInDjango20Warning, stacklevel=2
|
|
||||||
)
|
)
|
||||||
urlconf_module, app_name, namespace = arg
|
|
||||||
else:
|
else:
|
||||||
# No namespace hint - use manually provided namespace
|
# No namespace hint - use manually provided namespace
|
||||||
urlconf_module = arg
|
urlconf_module = arg
|
||||||
|
@ -51,12 +39,11 @@ def include(arg, namespace=None, app_name=None):
|
||||||
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
|
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
|
||||||
app_name = getattr(urlconf_module, 'app_name', app_name)
|
app_name = getattr(urlconf_module, 'app_name', app_name)
|
||||||
if namespace and not app_name:
|
if namespace and not app_name:
|
||||||
warnings.warn(
|
raise ImproperlyConfigured(
|
||||||
'Specifying a namespace in django.conf.urls.include() without '
|
'Specifying a namespace in django.conf.urls.include() without '
|
||||||
'providing an app_name is deprecated. Set the app_name attribute '
|
'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 '
|
'in the included module, or pass a 2-tuple containing the list of '
|
||||||
'patterns and app_name instead.',
|
'patterns and app_name instead.',
|
||||||
RemovedInDjango20Warning, stacklevel=2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
namespace = namespace or app_name
|
namespace = namespace or app_name
|
||||||
|
|
|
@ -53,10 +53,9 @@ parameter is useful.
|
||||||
``include()``
|
``include()``
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. function:: include(module, namespace=None, app_name=None)
|
.. function:: include(module, namespace=None)
|
||||||
include(pattern_list)
|
include(pattern_list)
|
||||||
include((pattern_list, app_namespace), namespace=None)
|
include((pattern_list, app_namespace), namespace=None)
|
||||||
include((pattern_list, app_namespace, instance_namespace))
|
|
||||||
|
|
||||||
A function that takes a full Python import path to another URLconf module
|
A function that takes a full Python import path to another URLconf module
|
||||||
that should be "included" in this place. Optionally, the :term:`application
|
that should be "included" in this place. Optionally, the :term:`application
|
||||||
|
@ -68,15 +67,12 @@ parameter is useful.
|
||||||
can be used to set a different instance namespace.
|
can be used to set a different instance namespace.
|
||||||
|
|
||||||
``include()`` also accepts as an argument either an iterable that returns
|
``include()`` also accepts as an argument either an iterable that returns
|
||||||
URL patterns, a 2-tuple containing such iterable plus the names of the
|
URL patterns or a 2-tuple containing such iterable plus the names of the
|
||||||
application namespaces, or a 3-tuple containing the iterable and the names
|
application namespaces.
|
||||||
of both the application and instance namespace.
|
|
||||||
|
|
||||||
:arg module: URLconf module (or module name)
|
:arg module: URLconf module (or module name)
|
||||||
:arg namespace: Instance namespace for the URL entries being included
|
:arg namespace: Instance namespace for the URL entries being included
|
||||||
:type namespace: string
|
:type namespace: string
|
||||||
:arg app_name: Application namespace for the URL entries being included
|
|
||||||
:type app_name: string
|
|
||||||
:arg pattern_list: Iterable of :func:`django.conf.urls.url` instances
|
:arg pattern_list: Iterable of :func:`django.conf.urls.url` instances
|
||||||
:arg app_namespace: Application namespace for the URL entries being included
|
:arg app_namespace: Application namespace for the URL entries being included
|
||||||
:type app_namespace: string
|
:type app_namespace: string
|
||||||
|
@ -85,20 +81,6 @@ parameter is useful.
|
||||||
|
|
||||||
See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`.
|
See :ref:`including-other-urlconfs` and :ref:`namespaces-and-include`.
|
||||||
|
|
||||||
.. deprecated:: 1.9
|
|
||||||
|
|
||||||
Support for the ``app_name`` argument is deprecated and will be removed in
|
|
||||||
Django 2.0. Specify the ``app_name`` as explained in
|
|
||||||
:ref:`namespaces-and-include` instead.
|
|
||||||
|
|
||||||
Support for passing a 3-tuple is also deprecated and will be removed in
|
|
||||||
Django 2.0. Pass a 2-tuple containing the pattern list and application
|
|
||||||
namespace, and use the ``namespace`` argument instead.
|
|
||||||
|
|
||||||
Lastly, support for an instance namespace without an application namespace
|
|
||||||
has been deprecated and will be removed in Django 2.0. Specify the
|
|
||||||
application namespace or remove the instance namespace.
|
|
||||||
|
|
||||||
``handler400``
|
``handler400``
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
|
|
@ -291,3 +291,11 @@ these features.
|
||||||
|
|
||||||
* The ``mime_type`` attribute of ``django.utils.feedgenerator.Atom1Feed`` and
|
* The ``mime_type`` attribute of ``django.utils.feedgenerator.Atom1Feed`` and
|
||||||
``django.utils.feedgenerator.RssFeed`` is removed.
|
``django.utils.feedgenerator.RssFeed`` is removed.
|
||||||
|
|
||||||
|
* The ``app_name`` argument to ``include()`` is removed.
|
||||||
|
|
||||||
|
* Support for passing a 3-tuple as the first argument to ``include()`` is
|
||||||
|
removed.
|
||||||
|
|
||||||
|
* Support for setting a URL instance namespace without an application namespace
|
||||||
|
is removed.
|
||||||
|
|
|
@ -6,6 +6,7 @@ from .views import empty_view, view_class_instance
|
||||||
testobj3 = URLObject('testapp', 'test-ns3')
|
testobj3 = URLObject('testapp', 'test-ns3')
|
||||||
testobj4 = URLObject('testapp', 'test-ns4')
|
testobj4 = URLObject('testapp', 'test-ns4')
|
||||||
|
|
||||||
|
app_name = 'included_namespace_urls'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^normal/$', empty_view, name='inc-normal-view'),
|
url(r'^normal/$', empty_view, name='inc-normal-view'),
|
||||||
url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', empty_view, name='inc-normal-view'),
|
url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', empty_view, name='inc-normal-view'),
|
||||||
|
@ -17,8 +18,8 @@ urlpatterns = [
|
||||||
|
|
||||||
url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'),
|
url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'),
|
||||||
|
|
||||||
url(r'^test3/', include(testobj3.urls)),
|
url(r'^test3/', include(*testobj3.urls)),
|
||||||
url(r'^test4/', include(testobj4.urls)),
|
url(r'^test4/', include(*testobj4.urls)),
|
||||||
url(r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')),
|
url(r'^ns-included3/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns3')),
|
||||||
url(r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')),
|
url(r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')),
|
||||||
]
|
]
|
||||||
|
|
|
@ -12,6 +12,7 @@ otherobj2 = URLObject('nodefault', 'other-ns2')
|
||||||
|
|
||||||
newappobj1 = URLObject('newapp')
|
newappobj1 = URLObject('newapp')
|
||||||
|
|
||||||
|
app_name = 'namespace_urls'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^normal/$', views.empty_view, name='normal-view'),
|
url(r'^normal/$', views.empty_view, name='normal-view'),
|
||||||
url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='normal-view'),
|
url(r'^normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view, name='normal-view'),
|
||||||
|
@ -27,12 +28,12 @@ urlpatterns = [
|
||||||
url(r'^unnamed/normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view),
|
url(r'^unnamed/normal/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.empty_view),
|
||||||
url(r'^unnamed/view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance),
|
url(r'^unnamed/view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', views.view_class_instance),
|
||||||
|
|
||||||
url(r'^test1/', include(testobj1.urls)),
|
url(r'^test1/', include(*testobj1.urls)),
|
||||||
url(r'^test2/', include(testobj2.urls)),
|
url(r'^test2/', include(*testobj2.urls)),
|
||||||
url(r'^default/', include(default_testobj.urls)),
|
url(r'^default/', include(*default_testobj.urls)),
|
||||||
|
|
||||||
url(r'^other1/', include(otherobj1.urls)),
|
url(r'^other1/', include(*otherobj1.urls)),
|
||||||
url(r'^other[246]/', include(otherobj2.urls)),
|
url(r'^other[246]/', include(*otherobj2.urls)),
|
||||||
|
|
||||||
url(r'^newapp1/', include(newappobj1.app_urls, 'new-ns1')),
|
url(r'^newapp1/', include(newappobj1.app_urls, 'new-ns1')),
|
||||||
url(r'^new-default/', include(newappobj1.app_urls)),
|
url(r'^new-default/', include(newappobj1.app_urls)),
|
||||||
|
@ -43,10 +44,12 @@ urlpatterns = [
|
||||||
url(r'^ns-included[135]/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns1')),
|
url(r'^ns-included[135]/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns1')),
|
||||||
url(r'^ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')),
|
url(r'^ns-included2/', include('urlpatterns_reverse.included_namespace_urls', namespace='inc-ns2')),
|
||||||
|
|
||||||
url(r'^app-included/', include('urlpatterns_reverse.included_namespace_urls', 'inc-app', 'inc-app')),
|
url(r'^app-included/', include('urlpatterns_reverse.included_namespace_urls', 'inc-app')),
|
||||||
|
|
||||||
url(r'^included/', include('urlpatterns_reverse.included_namespace_urls')),
|
url(r'^included/', include('urlpatterns_reverse.included_namespace_urls')),
|
||||||
url(r'^inc(?P<outer>[0-9]+)/', include('urlpatterns_reverse.included_urls', namespace='inc-ns5')),
|
url(
|
||||||
|
r'^inc(?P<outer>[0-9]+)/', include(('urlpatterns_reverse.included_urls', 'included_urls'), namespace='inc-ns5')
|
||||||
|
),
|
||||||
url(r'^included/([0-9]+)/', include('urlpatterns_reverse.included_namespace_urls')),
|
url(r'^included/([0-9]+)/', include('urlpatterns_reverse.included_namespace_urls')),
|
||||||
|
|
||||||
url(
|
url(
|
||||||
|
|
|
@ -18,16 +18,13 @@ from django.http import (
|
||||||
HttpRequest, HttpResponsePermanentRedirect, HttpResponseRedirect,
|
HttpRequest, HttpResponsePermanentRedirect, HttpResponseRedirect,
|
||||||
)
|
)
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.test import (
|
from django.test import SimpleTestCase, TestCase, override_settings
|
||||||
SimpleTestCase, TestCase, ignore_warnings, override_settings,
|
|
||||||
)
|
|
||||||
from django.test.utils import override_script_prefix
|
from django.test.utils import override_script_prefix
|
||||||
from django.urls import (
|
from django.urls import (
|
||||||
NoReverseMatch, RegexURLPattern, RegexURLResolver, Resolver404,
|
NoReverseMatch, RegexURLPattern, RegexURLResolver, Resolver404,
|
||||||
ResolverMatch, get_callable, get_resolver, resolve, reverse, reverse_lazy,
|
ResolverMatch, get_callable, get_resolver, resolve, reverse, reverse_lazy,
|
||||||
)
|
)
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
|
||||||
|
|
||||||
from . import middleware, urlconf_outer, views
|
from . import middleware, urlconf_outer, views
|
||||||
from .utils import URLObject
|
from .utils import URLObject
|
||||||
|
@ -42,23 +39,27 @@ resolve_test_data = (
|
||||||
{'arg1': '42', 'arg2': '37'}
|
{'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/included/normal/42/37/', 'inc-normal-view', '', '', 'inc-normal-view', views.empty_view, tuple(),
|
'/included/normal/42/37/', 'inc-normal-view', 'included_namespace_urls',
|
||||||
{'arg1': '42', 'arg2': '37'}
|
'included_namespace_urls', 'included_namespace_urls:inc-normal-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/included/view_class/42/37/', 'inc-view-class', '', '', 'inc-view-class', views.view_class_instance, tuple(),
|
'/included/view_class/42/37/', 'inc-view-class', 'included_namespace_urls',
|
||||||
{'arg1': '42', 'arg2': '37'}
|
'included_namespace_urls', 'included_namespace_urls:inc-view-class',
|
||||||
|
views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
|
|
||||||
# Unnamed args are dropped if you have *any* kwargs in a pattern
|
# Unnamed args are dropped if you have *any* kwargs in a pattern
|
||||||
('/mixed_args/42/37/', 'mixed-args', '', '', 'mixed-args', views.empty_view, tuple(), {'arg2': '37'}),
|
('/mixed_args/42/37/', 'mixed-args', '', '', 'mixed-args', views.empty_view, tuple(), {'arg2': '37'}),
|
||||||
(
|
(
|
||||||
'/included/mixed_args/42/37/', 'inc-mixed-args', '', '', 'inc-mixed-args', views.empty_view, tuple(),
|
'/included/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls',
|
||||||
{'arg2': '37'}
|
'included_namespace_urls', 'included_namespace_urls:inc-mixed-args',
|
||||||
|
views.empty_view, tuple(), {'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/included/12/mixed_args/42/37/', 'inc-mixed-args', '', '', 'inc-mixed-args', views.empty_view, tuple(),
|
'/included/12/mixed_args/42/37/', 'inc-mixed-args', 'included_namespace_urls',
|
||||||
{'arg2': '37'}
|
'included_namespace_urls', 'included_namespace_urls:inc-mixed-args',
|
||||||
|
views.empty_view, tuple(), {'arg2': '37'}
|
||||||
),
|
),
|
||||||
|
|
||||||
# Unnamed views should have None as the url_name. Regression data for #21157.
|
# Unnamed views should have None as the url_name. Regression data for #21157.
|
||||||
|
@ -73,10 +74,15 @@ resolve_test_data = (
|
||||||
|
|
||||||
# If you have no kwargs, you get an args list.
|
# If you have no kwargs, you get an args list.
|
||||||
('/no_kwargs/42/37/', 'no-kwargs', '', '', 'no-kwargs', views.empty_view, ('42', '37'), {}),
|
('/no_kwargs/42/37/', 'no-kwargs', '', '', 'no-kwargs', views.empty_view, ('42', '37'), {}),
|
||||||
('/included/no_kwargs/42/37/', 'inc-no-kwargs', '', '', 'inc-no-kwargs', views.empty_view, ('42', '37'), {}),
|
|
||||||
(
|
(
|
||||||
'/included/12/no_kwargs/42/37/', 'inc-no-kwargs', '', '', 'inc-no-kwargs', views.empty_view,
|
'/included/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls',
|
||||||
('12', '42', '37'), {}
|
'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs',
|
||||||
|
views.empty_view, ('42', '37'), {}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'/included/12/no_kwargs/42/37/', 'inc-no-kwargs', 'included_namespace_urls',
|
||||||
|
'included_namespace_urls', 'included_namespace_urls:inc-no-kwargs',
|
||||||
|
views.empty_view, ('12', '42', '37'), {}
|
||||||
),
|
),
|
||||||
|
|
||||||
# Namespaces
|
# Namespaces
|
||||||
|
@ -85,20 +91,23 @@ resolve_test_data = (
|
||||||
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view',
|
'/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp',
|
||||||
|
'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view',
|
||||||
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/ns-included1/normal/42/37/', 'inc-normal-view', '', 'inc-ns1', 'inc-ns1:inc-normal-view', views.empty_view,
|
'/ns-included1/normal/42/37/', 'inc-normal-view', 'included_namespace_urls',
|
||||||
tuple(), {'arg1': '42', 'arg2': '37'}
|
'inc-ns1', 'inc-ns1:inc-normal-view',
|
||||||
),
|
|
||||||
(
|
|
||||||
'/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view',
|
|
||||||
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/default/inner/42/37/', 'urlobject-view', 'testapp', 'testapp', 'testapp:urlobject-view', views.empty_view,
|
'/included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp',
|
||||||
tuple(), {'arg1': '42', 'arg2': '37'}
|
'included_namespace_urls:test-ns3', 'included_namespace_urls:test-ns3:urlobject-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'/default/inner/42/37/', 'urlobject-view', 'testapp', 'testapp', 'testapp:urlobject-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/other2/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns2', 'other-ns2:urlobject-view',
|
'/other2/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns2', 'other-ns2:urlobject-view',
|
||||||
|
@ -111,29 +120,37 @@ resolve_test_data = (
|
||||||
|
|
||||||
# Nested namespaces
|
# Nested namespaces
|
||||||
(
|
(
|
||||||
'/ns-included1/test3/inner/42/37/', 'urlobject-view', 'testapp', 'inc-ns1:test-ns3',
|
'/ns-included1/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp',
|
||||||
'inc-ns1:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
'inc-ns1:test-ns3', 'inc-ns1:test-ns3:urlobject-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'testapp',
|
'/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view',
|
||||||
'inc-ns1:inc-ns4:inc-ns2:test-ns3', 'inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view', views.empty_view,
|
'included_namespace_urls:namespace_urls:included_namespace_urls:testapp',
|
||||||
tuple(), {'arg1': '42', 'arg2': '37'}
|
'inc-ns1:inc-ns4:inc-ns2:test-ns3',
|
||||||
|
'inc-ns1:inc-ns4:inc-ns2:test-ns3:urlobject-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/app-included/test3/inner/42/37/', 'urlobject-view', 'inc-app:testapp', 'inc-app:test-ns3',
|
'/app-included/test3/inner/42/37/', 'urlobject-view', 'included_namespace_urls:testapp', 'inc-app:test-ns3',
|
||||||
'inc-app:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
'inc-app:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'/app-included/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'inc-app:testapp',
|
'/app-included/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view',
|
||||||
'inc-app:inc-ns4:inc-ns2:test-ns3', 'inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view', views.empty_view,
|
'included_namespace_urls:namespace_urls:included_namespace_urls:testapp',
|
||||||
tuple(), {'arg1': '42', 'arg2': '37'}
|
'inc-app:inc-ns4:inc-ns2:test-ns3',
|
||||||
|
'inc-app:inc-ns4:inc-ns2:test-ns3:urlobject-view',
|
||||||
|
views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}
|
||||||
),
|
),
|
||||||
|
|
||||||
# Namespaces capturing variables
|
# Namespaces capturing variables
|
||||||
('/inc70/', 'inner-nothing', '', 'inc-ns5', 'inc-ns5:inner-nothing', views.empty_view, tuple(), {'outer': '70'}),
|
|
||||||
(
|
(
|
||||||
'/inc78/extra/foobar/', 'inner-extra', '', 'inc-ns5', 'inc-ns5:inner-extra', views.empty_view, tuple(),
|
'/inc70/', 'inner-nothing', 'included_urls', 'inc-ns5', 'inc-ns5:inner-nothing',
|
||||||
{'outer': '78', 'extra': 'foobar'}
|
views.empty_view, tuple(), {'outer': '70'}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'/inc78/extra/foobar/', 'inner-extra', 'included_urls', 'inc-ns5', 'inc-ns5:inner-extra',
|
||||||
|
views.empty_view, tuple(), {'outer': '78', 'extra': 'foobar'}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -355,7 +372,6 @@ class URLPatternReverse(SimpleTestCase):
|
||||||
|
|
||||||
|
|
||||||
class ResolverTests(SimpleTestCase):
|
class ResolverTests(SimpleTestCase):
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_resolver_repr(self):
|
def test_resolver_repr(self):
|
||||||
"""
|
"""
|
||||||
Test repr of RegexURLResolver, especially when urlconf_name is a list
|
Test repr of RegexURLResolver, especially when urlconf_name is a list
|
||||||
|
@ -576,7 +592,6 @@ class ReverseShortcutTests(SimpleTestCase):
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls')
|
@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls')
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
class NamespaceTests(SimpleTestCase):
|
class NamespaceTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_ambiguous_object(self):
|
def test_ambiguous_object(self):
|
||||||
|
@ -613,10 +628,13 @@ class NamespaceTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_simple_included_name(self):
|
def test_simple_included_name(self):
|
||||||
"Normal lookups work on names included from other patterns"
|
"Normal lookups work on names included from other patterns"
|
||||||
self.assertEqual('/included/normal/', reverse('inc-normal-view'))
|
self.assertEqual('/included/normal/', reverse('included_namespace_urls:inc-normal-view'))
|
||||||
self.assertEqual('/included/normal/37/42/', reverse('inc-normal-view', args=[37, 42]))
|
self.assertEqual('/included/normal/37/42/', reverse('included_namespace_urls:inc-normal-view', args=[37, 42]))
|
||||||
self.assertEqual('/included/normal/42/37/', reverse('inc-normal-view', kwargs={'arg1': 42, 'arg2': 37}))
|
self.assertEqual(
|
||||||
self.assertEqual('/included/+%5C$*/', reverse('inc-special-view'))
|
'/included/normal/42/37/',
|
||||||
|
reverse('included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
||||||
|
)
|
||||||
|
self.assertEqual('/included/+%5C$*/', reverse('included_namespace_urls:inc-special-view'))
|
||||||
|
|
||||||
def test_namespace_object(self):
|
def test_namespace_object(self):
|
||||||
"Dynamic URL objects can be found using a namespace"
|
"Dynamic URL objects can be found using a namespace"
|
||||||
|
@ -643,12 +661,17 @@ class NamespaceTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_embedded_namespace_object(self):
|
def test_embedded_namespace_object(self):
|
||||||
"Namespaces can be installed anywhere in the URL pattern tree"
|
"Namespaces can be installed anywhere in the URL pattern tree"
|
||||||
self.assertEqual('/included/test3/inner/', reverse('test-ns3:urlobject-view'))
|
self.assertEqual('/included/test3/inner/', reverse('included_namespace_urls:test-ns3:urlobject-view'))
|
||||||
self.assertEqual('/included/test3/inner/37/42/', reverse('test-ns3:urlobject-view', args=[37, 42]))
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/included/test3/inner/42/37/', reverse('test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
'/included/test3/inner/37/42/', reverse('included_namespace_urls:test-ns3:urlobject-view', args=[37, 42])
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
'/included/test3/inner/42/37/',
|
||||||
|
reverse('included_namespace_urls:test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
'/included/test3/inner/+%5C$*/', reverse('included_namespace_urls:test-ns3:urlobject-special-view')
|
||||||
)
|
)
|
||||||
self.assertEqual('/included/test3/inner/+%5C$*/', reverse('test-ns3:urlobject-special-view'))
|
|
||||||
|
|
||||||
def test_namespace_pattern(self):
|
def test_namespace_pattern(self):
|
||||||
"Namespaces can be applied to include()'d urlpatterns"
|
"Namespaces can be applied to include()'d urlpatterns"
|
||||||
|
@ -718,17 +741,17 @@ class NamespaceTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_app_lookup_object_with_default(self):
|
def test_app_lookup_object_with_default(self):
|
||||||
"A default application namespace is sensitive to the 'current' app can be used for lookup"
|
"A default application namespace is sensitive to the 'current' app can be used for lookup"
|
||||||
self.assertEqual('/included/test3/inner/', reverse('testapp:urlobject-view', current_app='test-ns3'))
|
self.assertEqual('/default/inner/', reverse('testapp:urlobject-view', current_app='test-ns3'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/included/test3/inner/37/42/',
|
'/default/inner/37/42/',
|
||||||
reverse('testapp:urlobject-view', args=[37, 42], current_app='test-ns3')
|
reverse('testapp:urlobject-view', args=[37, 42], current_app='test-ns3')
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/included/test3/inner/42/37/',
|
'/default/inner/42/37/',
|
||||||
reverse('testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='test-ns3')
|
reverse('testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='test-ns3')
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/included/test3/inner/+%5C$*/', reverse('testapp:urlobject-special-view', current_app='test-ns3')
|
'/default/inner/+%5C$*/', reverse('testapp:urlobject-special-view', current_app='test-ns3')
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_app_lookup_object_without_default(self):
|
def test_app_lookup_object_without_default(self):
|
||||||
|
@ -749,13 +772,16 @@ class NamespaceTests(SimpleTestCase):
|
||||||
self.assertEqual('/other1/inner/+%5C$*/', reverse('nodefault:urlobject-special-view', current_app='other-ns1'))
|
self.assertEqual('/other1/inner/+%5C$*/', reverse('nodefault:urlobject-special-view', current_app='other-ns1'))
|
||||||
|
|
||||||
def test_special_chars_namespace(self):
|
def test_special_chars_namespace(self):
|
||||||
self.assertEqual('/+%5C$*/included/normal/', reverse('special:inc-normal-view'))
|
self.assertEqual('/+%5C$*/included/normal/', reverse('special:included_namespace_urls:inc-normal-view'))
|
||||||
self.assertEqual('/+%5C$*/included/normal/37/42/', reverse('special:inc-normal-view', args=[37, 42]))
|
self.assertEqual(
|
||||||
|
'/+%5C$*/included/normal/37/42/',
|
||||||
|
reverse('special:included_namespace_urls:inc-normal-view', args=[37, 42])
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/+%5C$*/included/normal/42/37/',
|
'/+%5C$*/included/normal/42/37/',
|
||||||
reverse('special:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
reverse('special:included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
||||||
)
|
)
|
||||||
self.assertEqual('/+%5C$*/included/+%5C$*/', reverse('special:inc-special-view'))
|
self.assertEqual('/+%5C$*/included/+%5C$*/', reverse('special:included_namespace_urls:inc-special-view'))
|
||||||
|
|
||||||
def test_namespaces_with_variables(self):
|
def test_namespaces_with_variables(self):
|
||||||
"Namespace prefixes can capture variables: see #15900"
|
"Namespace prefixes can capture variables: see #15900"
|
||||||
|
@ -965,7 +991,6 @@ class NoRootUrlConfTests(SimpleTestCase):
|
||||||
@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls')
|
@override_settings(ROOT_URLCONF='urlpatterns_reverse.namespace_urls')
|
||||||
class ResolverMatchTests(SimpleTestCase):
|
class ResolverMatchTests(SimpleTestCase):
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_urlpattern_resolve(self):
|
def test_urlpattern_resolve(self):
|
||||||
for path, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data:
|
for path, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data:
|
||||||
# Test legacy support for extracting "function, args, kwargs"
|
# Test legacy support for extracting "function, args, kwargs"
|
||||||
|
@ -990,7 +1015,6 @@ class ResolverMatchTests(SimpleTestCase):
|
||||||
self.assertEqual(match[1], args)
|
self.assertEqual(match[1], args)
|
||||||
self.assertEqual(match[2], kwargs)
|
self.assertEqual(match[2], kwargs)
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_resolver_match_on_request(self):
|
def test_resolver_match_on_request(self):
|
||||||
response = self.client.get('/resolver_match/')
|
response = self.client.get('/resolver_match/')
|
||||||
resolver_match = response.resolver_match
|
resolver_match = response.resolver_match
|
||||||
|
@ -1042,34 +1066,21 @@ class IncludeTests(SimpleTestCase):
|
||||||
]
|
]
|
||||||
app_urls = URLObject('inc-app')
|
app_urls = URLObject('inc-app')
|
||||||
|
|
||||||
def test_include_app_name_but_no_namespace(self):
|
|
||||||
msg = "Must specify a namespace if specifying app_name."
|
|
||||||
with self.assertRaisesMessage(ValueError, msg):
|
|
||||||
include(self.url_patterns, app_name='bar')
|
|
||||||
|
|
||||||
def test_include_urls(self):
|
def test_include_urls(self):
|
||||||
self.assertEqual(include(self.url_patterns), (self.url_patterns, None, None))
|
self.assertEqual(include(self.url_patterns), (self.url_patterns, None, None))
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_include_namespace(self):
|
def test_include_namespace(self):
|
||||||
# no app_name -> deprecated
|
msg = (
|
||||||
self.assertEqual(include(self.url_patterns, 'namespace'), (self.url_patterns, None, 'namespace'))
|
"Specifying a namespace in django.conf.urls.include() without "
|
||||||
|
"providing an app_name is not supported."
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_include_namespace_app_name(self):
|
|
||||||
# app_name argument to include -> deprecated
|
|
||||||
self.assertEqual(
|
|
||||||
include(self.url_patterns, 'namespace', 'app_name'),
|
|
||||||
(self.url_patterns, 'app_name', 'namespace')
|
|
||||||
)
|
)
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
|
include(self.url_patterns, 'namespace')
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_include_3_tuple(self):
|
def test_include_3_tuple(self):
|
||||||
# 3-tuple -> deprecated
|
msg = 'Passing a 3-tuple to django.conf.urls.include() is not supported.'
|
||||||
self.assertEqual(
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
include((self.url_patterns, 'app_name', 'namespace')),
|
include((self.url_patterns, 'app_name', 'namespace'))
|
||||||
(self.url_patterns, 'app_name', 'namespace')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_include_2_tuple(self):
|
def test_include_2_tuple(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
|
@ -18,7 +18,7 @@ class URLObject(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def urls(self):
|
def urls(self):
|
||||||
return self.urlpatterns, self.app_name, self.namespace
|
return (self.urlpatterns, self.app_name), self.namespace
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app_urls(self):
|
def app_urls(self):
|
||||||
|
|
Loading…
Reference in New Issue