Fixed #24906 -- Fixed ResolverMatch.app_name for nested namespaces.
Set ResolverMatch.app_name to the full path of nested application namespaces.
This commit is contained in:
parent
1ea87c8c79
commit
bc77eb6d08
|
@ -37,12 +37,16 @@ _urlconfs = local()
|
||||||
|
|
||||||
|
|
||||||
class ResolverMatch(object):
|
class ResolverMatch(object):
|
||||||
def __init__(self, func, args, kwargs, url_name=None, app_name=None, namespaces=None):
|
def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None):
|
||||||
self.func = func
|
self.func = func
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.url_name = url_name
|
self.url_name = url_name
|
||||||
self.app_name = app_name
|
|
||||||
|
# If a URLRegexResolver doesn't have a namespace or app_name, it passes
|
||||||
|
# in an empty value.
|
||||||
|
self.app_names = [x for x in app_names if x] if app_names else []
|
||||||
|
self.app_name = ':'.join(self.app_names)
|
||||||
|
|
||||||
if namespaces:
|
if namespaces:
|
||||||
self.namespaces = [x for x in namespaces if x]
|
self.namespaces = [x for x in namespaces if x]
|
||||||
|
@ -64,8 +68,8 @@ class ResolverMatch(object):
|
||||||
return (self.func, self.args, self.kwargs)[index]
|
return (self.func, self.args, self.kwargs)[index]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "ResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_name=%s, namespaces=%s)" % (
|
return "ResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_names=%s, namespaces=%s)" % (
|
||||||
self._func_path, self.args, self.kwargs, self.url_name, self.app_name, self.namespaces)
|
self._func_path, self.args, self.kwargs, self.url_name, self.app_names, self.namespaces)
|
||||||
|
|
||||||
|
|
||||||
class Resolver404(Http404):
|
class Resolver404(Http404):
|
||||||
|
@ -395,7 +399,7 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
sub_match_args,
|
sub_match_args,
|
||||||
sub_match_dict,
|
sub_match_dict,
|
||||||
sub_match.url_name,
|
sub_match.url_name,
|
||||||
self.app_name or sub_match.app_name,
|
[self.app_name] + sub_match.app_names,
|
||||||
[self.namespace] + sub_match.namespaces
|
[self.namespace] + sub_match.namespaces
|
||||||
)
|
)
|
||||||
tried.append([pattern])
|
tried.append([pattern])
|
||||||
|
|
|
@ -155,6 +155,15 @@ If the URL does not resolve, the function raises a
|
||||||
The application namespace for the URL pattern that matches the
|
The application namespace for the URL pattern that matches the
|
||||||
URL.
|
URL.
|
||||||
|
|
||||||
|
.. attribute:: ResolverMatch.app_names
|
||||||
|
|
||||||
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The list of individual namespace components in the full
|
||||||
|
application namespace for the URL pattern that matches the URL.
|
||||||
|
For example, if the ``app_name`` is ``'foo:bar'``, then ``app_names``
|
||||||
|
will be ``['foo', 'bar']``.
|
||||||
|
|
||||||
.. attribute:: ResolverMatch.namespace
|
.. attribute:: ResolverMatch.namespace
|
||||||
|
|
||||||
The instance namespace for the URL pattern that matches the
|
The instance namespace for the URL pattern that matches the
|
||||||
|
|
|
@ -597,6 +597,13 @@ Miscellaneous
|
||||||
:attr:`~django.test.SimpleTestCase.allow_database_queries` class attribute
|
:attr:`~django.test.SimpleTestCase.allow_database_queries` class attribute
|
||||||
to ``True`` on your test class.
|
to ``True`` on your test class.
|
||||||
|
|
||||||
|
* :attr:`ResolverMatch.app_name
|
||||||
|
<django.core.urlresolvers.ResolverMatch.app_name>` was changed to contain
|
||||||
|
the full namespace path in the case of nested namespaces. For consistency
|
||||||
|
with :attr:`ResolverMatch.namespace
|
||||||
|
<django.core.urlresolvers.ResolverMatch.namespace>`, the empty value is now
|
||||||
|
an empty string instead of ``None``.
|
||||||
|
|
||||||
.. _deprecated-features-1.9:
|
.. _deprecated-features-1.9:
|
||||||
|
|
||||||
Features deprecated in 1.9
|
Features deprecated in 1.9
|
||||||
|
|
|
@ -48,6 +48,8 @@ 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'^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', 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')),
|
||||||
|
|
|
@ -34,29 +34,29 @@ from .views import empty_view
|
||||||
resolve_test_data = (
|
resolve_test_data = (
|
||||||
# These entries are in the format: (path, url_name, app_name, namespace, view_name, func, args, kwargs)
|
# These entries are in the format: (path, url_name, app_name, namespace, view_name, func, args, kwargs)
|
||||||
# Simple case
|
# Simple case
|
||||||
('/normal/42/37/', 'normal-view', None, '', 'normal-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/normal/42/37/', 'normal-view', '', '', 'normal-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/view_class/42/37/', 'view-class', None, '', 'view-class', views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/view_class/42/37/', 'view-class', '', '', 'view-class', views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/included/normal/42/37/', 'inc-normal-view', None, '', 'inc-normal-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/included/normal/42/37/', 'inc-normal-view', '', '', 'inc-normal-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/included/view_class/42/37/', 'inc-view-class', None, '', 'inc-view-class', views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/included/view_class/42/37/', 'inc-view-class', '', '', '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', None, '', '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', None, '', 'inc-mixed-args', views.empty_view, tuple(), {'arg2': '37'}),
|
('/included/mixed_args/42/37/', 'inc-mixed-args', '', '', 'inc-mixed-args', views.empty_view, tuple(), {'arg2': '37'}),
|
||||||
('/included/12/mixed_args/42/37/', 'inc-mixed-args', None, '', '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(), {'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.
|
||||||
('/unnamed/normal/42/37/', None, None, '', 'urlpatterns_reverse.views.empty_view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/unnamed/normal/42/37/', None, '', '', 'urlpatterns_reverse.views.empty_view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/unnamed/view_class/42/37/', None, None, '', 'urlpatterns_reverse.views.ViewClass', views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/unnamed/view_class/42/37/', None, '', '', 'urlpatterns_reverse.views.ViewClass', views.view_class_instance, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
|
|
||||||
# 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', None, '', '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', None, '', 'inc-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', None, '', 'inc-no-kwargs', views.empty_view, ('12', '42', '37'), {}),
|
('/included/12/no_kwargs/42/37/', 'inc-no-kwargs', '', '', 'inc-no-kwargs', views.empty_view, ('12', '42', '37'), {}),
|
||||||
|
|
||||||
# Namespaces
|
# Namespaces
|
||||||
('/test1/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns1', 'test-ns1:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/test1/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns1', 'test-ns1:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/ns-included1/normal/42/37/', 'inc-normal-view', None, 'inc-ns1', 'inc-ns1:inc-normal-view', 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, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
('/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', 'test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/included/test3/inner/42/37/', 'urlobject-view', 'testapp', 'test-ns3', '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'}),
|
('/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', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/other2/inner/42/37/', 'urlobject-view', 'nodefault', 'other-ns2', 'other-ns2:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
||||||
|
@ -65,10 +65,12 @@ resolve_test_data = (
|
||||||
# Nested namespaces
|
# Nested namespaces
|
||||||
('/ns-included1/test3/inner/42/37/', 'urlobject-view', 'testapp', 'inc-ns1:test-ns3', 'inc-ns1:test-ns3:urlobject-view', views.empty_view, tuple(), {'arg1': '42', 'arg2': '37'}),
|
('/ns-included1/test3/inner/42/37/', 'urlobject-view', 'testapp', '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', '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'}),
|
('/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'testapp', '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', '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', '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', None, 'inc-ns5', 'inc-ns5:inner-nothing', views.empty_view, tuple(), {'outer': '70'}),
|
('/inc70/', 'inner-nothing', '', 'inc-ns5', 'inc-ns5:inner-nothing', views.empty_view, tuple(), {'outer': '70'}),
|
||||||
('/inc78/extra/foobar/', 'inner-extra', None, 'inc-ns5', 'inc-ns5:inner-extra', views.empty_view, tuple(), {'outer': '78', 'extra': 'foobar'}),
|
('/inc78/extra/foobar/', 'inner-extra', '', 'inc-ns5', 'inc-ns5:inner-extra', views.empty_view, tuple(), {'outer': '78', 'extra': 'foobar'}),
|
||||||
)
|
)
|
||||||
|
|
||||||
test_data = (
|
test_data = (
|
||||||
|
|
Loading…
Reference in New Issue