Ticket #17914: 17914.patch
File 17914.patch, 8.0 KB (added by , 13 years ago) |
---|
-
tests/regressiontests/urlpatterns_reverse/views.py
26 26 return HttpResponse('') 27 27 28 28 view_class_instance = ViewClass() 29 view_class_instance2 = ViewClass() 29 30 30 31 class LazyRedirectView(RedirectView): 31 32 url = reverse_lazy('named-lazy-url-redirected-to') -
tests/regressiontests/urlpatterns_reverse/namespace_urls.py
54 54 55 55 (r'^ns-outer/(?P<outer>\d+)/', include('regressiontests.urlpatterns_reverse.included_namespace_urls', namespace='inc-outer')), 56 56 57 (r'^\+\\\$\*/ ', include('regressiontests.urlpatterns_reverse.namespace_urls', namespace='special')),57 (r'^\+\\\$\*/included/', include('regressiontests.urlpatterns_reverse.included_namespace_urls', namespace='special')), 58 58 ) -
tests/regressiontests/urlpatterns_reverse/tests.py
47 47 48 48 # Nested namespaces 49 49 ('/ns-included1/test3/inner/42/37/', 'urlobject-view', 'testapp', 'inc-ns1:test-ns3', 'empty_view', tuple(), {'arg1': '42', 'arg2': '37'}), 50 ('/ns-included1/ns-included4/ns-included2/test3/inner/42/37/', 'urlobject-view', 'testapp', 'inc-ns1:inc-ns4:inc-ns2:test-ns3', 'empty_view', tuple(), {'arg1': '42', 'arg2': '37'}),51 50 52 51 # Namespaces capturing variables 53 52 ('/inc70/', 'inner-nothing', None, 'inc-ns5', views.empty_view, tuple(), {'outer': '70'}), … … 278 277 class NamespaceTests(TestCase): 279 278 urls = 'regressiontests.urlpatterns_reverse.namespace_urls' 280 279 280 def test_function_reference(self): 281 self.assertEqual(reverse(views.view_class_instance2), '/+%5C$*/included/view_class/level2/') 282 281 283 def test_ambiguous_object(self): 282 284 "Names deployed via dynamic URL objects that require namespaces can't be resolved" 283 285 self.assertRaises(NoReverseMatch, reverse, 'urlobject-view') … … 346 348 self.assertEqual('/ns-included1/test3/inner/42/37/', reverse('inc-ns1:test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37})) 347 349 self.assertEqual('/ns-included1/test3/inner/+%5C$*/', reverse('inc-ns1:test-ns3:urlobject-special-view')) 348 350 349 def test_nested_namespace_pattern(self):350 "Namespaces can be nested"351 self.assertEqual('/ns-included1/ns-included4/ns-included1/test3/inner/', reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view'))352 self.assertEqual('/ns-included1/ns-included4/ns-included1/test3/inner/37/42/', reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', args=[37,42]))353 self.assertEqual('/ns-included1/ns-included4/ns-included1/test3/inner/42/37/', reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37}))354 self.assertEqual('/ns-included1/ns-included4/ns-included1/test3/inner/+%5C$*/', reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-special-view'))355 356 351 def test_app_lookup_object(self): 357 352 "A default application namespace can be used for lookup" 358 353 self.assertEqual('/default/inner/', reverse('testapp:urlobject-view')) -
tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py
3 3 from django.conf.urls import patterns, url, include 4 4 5 5 from .namespace_urls import URLObject 6 from .views import view_class_instance 6 from .views import view_class_instance, view_class_instance2 7 7 8 8 9 9 testobj3 = URLObject('testapp', 'test-ns3') 10 10 11 level2_patterns = patterns("", 12 (r'^level2/$', view_class_instance2) 13 ) 14 11 15 urlpatterns = patterns('regressiontests.urlpatterns_reverse.views', 12 16 url(r'^normal/$', 'empty_view', name='inc-normal-view'), 13 17 url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='inc-normal-view'), … … 18 22 url(r'^no_kwargs/(\d+)/(\d+)/$', 'empty_view', name='inc-no-kwargs'), 19 23 20 24 url(r'^view_class/(?P<arg1>\d+)/(?P<arg2>\d+)/$', view_class_instance, name='inc-view-class'), 25 url(r'^view_class/', include(level2_patterns)), 21 26 22 27 (r'^test3/', include(testobj3.urls)), 23 28 (r'^ns-included3/', include('regressiontests.urlpatterns_reverse.included_urls', namespace='inc-ns3')), 24 (r'^ns-included4/', include('regressiontests.urlpatterns_reverse.namespace_urls', namespace='inc-ns4')),25 29 ) 26 30 -
django/core/urlresolvers.py
7 7 (view_function, function_args, function_kwargs) 8 8 """ 9 9 10 from itertools import ifilter 10 11 import re 11 12 from threading import local 12 13 … … 248 249 namespaces[pattern.namespace] = (p_pattern, pattern) 249 250 if pattern.app_name: 250 251 apps.setdefault(pattern.app_name, []).append(pattern.namespace) 252 # Since a namespace has been provided for the included resolver, 253 # we can rely on urlresolvers.reverse() to traverse the tree 254 # to honor and find the correct resolver to finally be able to 255 # call resolver.reverse(name). 256 # However when reversing a callable, no namespace information 257 # is attached to the callable so all lookups for all descendant 258 # views functions *must* be included in each resolver. 259 include_lookups = ifilter(callable, pattern.reverse_dict) 251 260 else: 252 parent = normalize(pattern.regex.pattern)253 for name in pattern.reverse_dict:254 for matches, pat, defaults in pattern.reverse_dict.getlist(name):255 new_matches = []256 for piece, p_args in parent:257 new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches])258 lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs)))259 261 for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items(): 260 262 namespaces[namespace] = (p_pattern + prefix, sub_pattern) 261 263 for app_name, namespace_list in pattern.app_dict.items(): 262 264 apps.setdefault(app_name, []).extend(namespace_list) 265 # When no namespace is provided, *all* the patterns in the 266 # included resolver should be available in this resolver. 267 include_lookups = iter(pattern.reverse_dict) 268 # Add each of the child lookups to this resolver, being careful 269 # to add appropriate URL and regex prefixes so reversing results 270 # are correct. 271 parent = normalize(pattern.regex.pattern) 272 for name in include_lookups: 273 for matches, pat, defaults in pattern.reverse_dict.getlist(name): 274 new_matches = [] 275 for piece, p_args in parent: 276 new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches]) 277 lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs))) 263 278 else: 264 279 bits = normalize(p_pattern) 265 280 lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))