﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
17914	Add support for namespaced view references when passing a callable to reverse()	Bradley Ayers <bradley.ayers@…>	nobody	"It's not possible to reverse a URL by passing a function reference to reverse()
that's hooked into the URLconf under a namespace.

Consider the trivial Django project (that doesn't work):

{{{
# urls.py
from django.conf.urls.defaults import patterns, include
from django.core.urlresolvers import reverse
from django.http import HttpResponse

def view(request):
    # Return the URL to this view
    return HttpResponse(reverse(view))

level2 = patterns('',
    (r'^2/', view)
)

urlpatterns = patterns('',
    (r'^1/', include(level2, namespace=""foo""))
)
}}}

Removing ``, namespace=""foo""`` will make it work.

My understanding of why this happens, is that `reverse()` traverses `RegexURLResolver`s
*only* for strings. Function references are passed directly to the root `RegexURLResolver.reverse`
method.:

{{{
# from django/core/urlresolvers.py ~ line 432

if not isinstance(viewname, basestring):
    view = viewname
else:
    # <snip> -- resolver traversal happens here to honor namespaces
    # `resolver` is reassigned to last RegexURLResolver in namespace chain

return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
}}}

Obviously traversing namespaces isn't possible for a function reference,
so what's needed is to add *all* descendent view references into each `RegexURLResolver`'s 
`reverse_dict` dictionary.

Populating `reverse_dict` is lazy and happens on first access, the work is
performed in `RegexURLResolver._populate`:

{{{
# django/core/urlresolvers.py ~ line 237
def _populate(self):
    # <snip>
    for pattern in reversed(self.url_patterns):
        # <snip>
        if isinstance(pattern, RegexURLResolver):
            if pattern.namespace:
                # <snip> -- tldr `self.reverse_dict` isn't populated, `pattern` (the
                #           RegexURLResolver) is instead stored in `self.namespace_dict`
            else:
                # <snip> -- tldr `self.reverse_dict` *is* populated with the keys
                #           being the name of each URL (or the function reference)
                #           defined in this level. (i.e. only children, not all descendants)
        else:
            # <snip> -- tldr `self.reverse_dict` is again populated
}}}

This combination of behaviour by `RegexURLResolver._populate` and `reverse()`
leads to the problem.
"	Bug	closed	Core (URLs)	dev	Normal	wontfix		bradley.ayers@… amirouche.boubekki@… gwahl@… Florian Apolloner	Accepted	1	0	0	0	0	0
