Ticket #11559: 11559.patch

File 11559.patch, 3.4 KB (added by ungenio, 4 years ago)

Added some polish to patch from #12950. Includes test.

  • tests/regressiontests/urlpatterns_reverse/namespace_urls.py

     
    4444
    4545    (r'^included/', include('regressiontests.urlpatterns_reverse.included_namespace_urls')),
    4646
     47    (r'^ns-outer/(?P<outer>\d+)/', include('regressiontests.urlpatterns_reverse.included_namespace_urls', namespace='inc-outer')),
     48
    4749)
  • tests/regressiontests/urlpatterns_reverse/tests.py

     
    306306        self.assertEqual('/ns-included1/normal/', reverse('inc-ns1:inc-normal-view'))
    307307        self.assertEqual('/ns-included1/normal/37/42/', reverse('inc-ns1:inc-normal-view', args=[37,42]))
    308308        self.assertEqual('/ns-included1/normal/42/37/', reverse('inc-ns1:inc-normal-view', kwargs={'arg1':42, 'arg2':37}))
     309        self.assertEqual('/ns-outer/42/normal/', reverse('inc-outer:inc-normal-view', kwargs={'outer':42}))
    309310
    310311    def test_multiple_namespace_pattern(self):
    311312        "Namespaces can be embedded"
  • django/core/urlresolvers.py

     
    2020from django.utils.regex_helper import normalize
    2121
    2222_resolver_cache = {} # Maps URLconf modules to RegexURLResolver instances.
     23_ns_resolver_cache = {} # Maps namespaces to RegexURLResolver instances.
    2324_callable_cache = {} # Maps view and url pattern names to their view functions.
    2425
    2526# SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for
     
    106107    return RegexURLResolver(r'^/', urlconf)
    107108get_resolver = memoize(get_resolver, _resolver_cache, 1)
    108109
     110def get_ns_resolver(ns_pattern, resolver):
     111    # Build a namespaced resolver for the given parent urlconf pattern.
     112    # This makes it possible to have captured parameters in the parent
     113    # urlconf pattern.
     114    ns_resolver = RegexURLResolver(ns_pattern, resolver.url_patterns)
     115    return RegexURLResolver(r'^/', [ns_resolver])
     116get_ns_resolver = memoize(get_ns_resolver, _ns_resolver_cache, 2)
     117
    109118def get_mod_func(callback):
    110119    # Converts 'django.views.news.stories.story_detail' to
    111120    # ['django.views.news.stories', 'story_detail']
     
    360369        path = parts[1:]
    361370
    362371        resolved_path = []
     372        ns_pattern = ''
    363373        while path:
    364374            ns = path.pop()
    365375
     
    380390            try:
    381391                extra, resolver = resolver.namespace_dict[ns]
    382392                resolved_path.append(ns)
    383                 prefix = prefix + extra
     393                ns_pattern = ns_pattern + extra
    384394            except KeyError, key:
    385395                if resolved_path:
    386396                    raise NoReverseMatch("%s is not a registered namespace inside '%s'" % (key, ':'.join(resolved_path)))
    387397                else:
    388398                    raise NoReverseMatch("%s is not a registered namespace" % key)
     399        if ns_pattern:
     400            resolver = get_ns_resolver(ns_pattern, resolver)
    389401
    390402    return iri_to_uri(u'%s%s' % (prefix, resolver.reverse(view,
    391403            *args, **kwargs)))
Back to Top