Loading django/core/urlresolvers.py +12 −2 Original line number Diff line number Diff line Loading @@ -549,19 +549,26 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): view = parts[0] path = parts[1:] if current_app: current_path = current_app.split(':') current_path.reverse() else: current_path = None resolved_path = [] ns_pattern = '' while path: ns = path.pop() current_ns = current_path.pop() if current_path else None # Lookup the name to see if it could be an app identifier try: app_list = resolver.app_dict[ns] # Yes! Path part matches an app in the current Resolver if current_app and current_app in app_list: if current_ns and current_ns in app_list: # If we are reversing for a particular app, # use that namespace ns = current_app ns = current_ns elif ns not in app_list: # The name isn't shared by one of the instances # (i.e., the default) so just pick the first instance Loading @@ -570,6 +577,9 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): except KeyError: pass if ns != current_ns: current_path = None try: extra, resolver = resolver.namespace_dict[ns] resolved_path.append(ns) Loading tests/urlpatterns_reverse/included_namespace_urls.py +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from .namespace_urls import URLObject from .views import view_class_instance testobj3 = URLObject('testapp', 'test-ns3') testobj4 = URLObject('testapp', 'test-ns4') # test deprecated patterns() function. convert to list of urls() in Django 2.0 with warnings.catch_warnings(): Loading @@ -24,6 +25,7 @@ with warnings.catch_warnings(): url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'), (r'^test3/', include(testobj3.urls)), (r'^test4/', include(testobj4.urls)), (r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')), (r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')), ) tests/urlpatterns_reverse/tests.py +47 −0 Original line number Diff line number Diff line Loading @@ -574,6 +574,53 @@ class NamespaceTests(SimpleTestCase): self.assertEqual('/inc70/', reverse('inc-ns5:inner-nothing', args=['70'])) self.assertEqual('/inc78/extra/foobar/', reverse('inc-ns5:inner-extra', args=['78', 'foobar'])) def test_nested_app_lookup(self): "A nested current_app should be split in individual namespaces (#24904)" self.assertEqual('/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view')) self.assertEqual('/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42])) self.assertEqual( '/ns-included1/test4/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}) ) self.assertEqual('/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view')) self.assertEqual( '/ns-included1/test3/inner/', reverse('inc-ns1:testapp:urlobject-view', current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view', current_app='inc-ns1:test-ns3') ) def test_current_app_no_partial_match(self): "current_app should either match the whole path or shouldn't be used" self.assertEqual( '/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view', current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view', current_app='non-existant:test-ns3') ) @override_settings(ROOT_URLCONF=urlconf_outer.__name__) class RequestURLconfTests(SimpleTestCase): Loading Loading
django/core/urlresolvers.py +12 −2 Original line number Diff line number Diff line Loading @@ -549,19 +549,26 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): view = parts[0] path = parts[1:] if current_app: current_path = current_app.split(':') current_path.reverse() else: current_path = None resolved_path = [] ns_pattern = '' while path: ns = path.pop() current_ns = current_path.pop() if current_path else None # Lookup the name to see if it could be an app identifier try: app_list = resolver.app_dict[ns] # Yes! Path part matches an app in the current Resolver if current_app and current_app in app_list: if current_ns and current_ns in app_list: # If we are reversing for a particular app, # use that namespace ns = current_app ns = current_ns elif ns not in app_list: # The name isn't shared by one of the instances # (i.e., the default) so just pick the first instance Loading @@ -570,6 +577,9 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None): except KeyError: pass if ns != current_ns: current_path = None try: extra, resolver = resolver.namespace_dict[ns] resolved_path.append(ns) Loading
tests/urlpatterns_reverse/included_namespace_urls.py +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from .namespace_urls import URLObject from .views import view_class_instance testobj3 = URLObject('testapp', 'test-ns3') testobj4 = URLObject('testapp', 'test-ns4') # test deprecated patterns() function. convert to list of urls() in Django 2.0 with warnings.catch_warnings(): Loading @@ -24,6 +25,7 @@ with warnings.catch_warnings(): url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'), (r'^test3/', include(testobj3.urls)), (r'^test4/', include(testobj4.urls)), (r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')), (r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')), )
tests/urlpatterns_reverse/tests.py +47 −0 Original line number Diff line number Diff line Loading @@ -574,6 +574,53 @@ class NamespaceTests(SimpleTestCase): self.assertEqual('/inc70/', reverse('inc-ns5:inner-nothing', args=['70'])) self.assertEqual('/inc78/extra/foobar/', reverse('inc-ns5:inner-extra', args=['78', 'foobar'])) def test_nested_app_lookup(self): "A nested current_app should be split in individual namespaces (#24904)" self.assertEqual('/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view')) self.assertEqual('/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42])) self.assertEqual( '/ns-included1/test4/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}) ) self.assertEqual('/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view')) self.assertEqual( '/ns-included1/test3/inner/', reverse('inc-ns1:testapp:urlobject-view', current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='inc-ns1:test-ns3') ) self.assertEqual( '/ns-included1/test3/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view', current_app='inc-ns1:test-ns3') ) def test_current_app_no_partial_match(self): "current_app should either match the whole path or shouldn't be used" self.assertEqual( '/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view', current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/42/37/', reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='non-existant:test-ns3') ) self.assertEqual( '/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view', current_app='non-existant:test-ns3') ) @override_settings(ROOT_URLCONF=urlconf_outer.__name__) class RequestURLconfTests(SimpleTestCase): Loading