mirror of https://github.com/django/django.git
[1.10.x] Fixed #24931 -- Made namespaced RegexURLResolvers populate callback strings.
Fixed a regression in2f16ff5a6c
. Thanks Tim Graham for the review. Backport of625b8e9295
from master
This commit is contained in:
parent
1213ef2b18
commit
31a789f646
|
@ -164,6 +164,7 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
# urlpatterns
|
# urlpatterns
|
||||||
self._callback_strs = set()
|
self._callback_strs = set()
|
||||||
self._populated = False
|
self._populated = False
|
||||||
|
self._populating = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if isinstance(self.urlconf_name, list) and len(self.urlconf_name):
|
if isinstance(self.urlconf_name, list) and len(self.urlconf_name):
|
||||||
|
@ -177,6 +178,9 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _populate(self):
|
def _populate(self):
|
||||||
|
if self._populating:
|
||||||
|
return
|
||||||
|
self._populating = True
|
||||||
lookups = MultiValueDict()
|
lookups = MultiValueDict()
|
||||||
namespaces = {}
|
namespaces = {}
|
||||||
apps = {}
|
apps = {}
|
||||||
|
@ -209,7 +213,9 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
|
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
|
||||||
for app_name, namespace_list in pattern.app_dict.items():
|
for app_name, namespace_list in pattern.app_dict.items():
|
||||||
apps.setdefault(app_name, []).extend(namespace_list)
|
apps.setdefault(app_name, []).extend(namespace_list)
|
||||||
self._callback_strs.update(pattern._callback_strs)
|
if not pattern._populating:
|
||||||
|
pattern._populate()
|
||||||
|
self._callback_strs.update(pattern._callback_strs)
|
||||||
else:
|
else:
|
||||||
bits = normalize(p_pattern)
|
bits = normalize(p_pattern)
|
||||||
lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))
|
lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))
|
||||||
|
@ -219,6 +225,7 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
self._namespace_dict[language_code] = namespaces
|
self._namespace_dict[language_code] = namespaces
|
||||||
self._app_dict[language_code] = apps
|
self._app_dict[language_code] = apps
|
||||||
self._populated = True
|
self._populated = True
|
||||||
|
self._populating = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reverse_dict(self):
|
def reverse_dict(self):
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.conf.urls import include, url
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
backend_urls = ([
|
||||||
|
url(r'^something/$', views.XViewClass.as_view(), name='something'),
|
||||||
|
], 'backend')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||||
|
url(r'^admin/', admin.site.urls),
|
||||||
|
url(r'^api/backend/', include(backend_urls, namespace='backend')),
|
||||||
|
]
|
|
@ -88,6 +88,12 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
||||||
# View docstring
|
# View docstring
|
||||||
self.assertContains(response, 'Base view for admindocs views.')
|
self.assertContains(response, 'Base view for admindocs views.')
|
||||||
|
|
||||||
|
@override_settings(ROOT_URLCONF='admin_docs.namespace_urls')
|
||||||
|
def test_namespaced_view_detail(self):
|
||||||
|
url = reverse('django-admindocs-views-detail', args=['admin_docs.views.XViewClass'])
|
||||||
|
response = self.client.get(url)
|
||||||
|
self.assertContains(response, '<h1>admin_docs.views.XViewClass</h1>')
|
||||||
|
|
||||||
def test_view_detail_illegal_import(self):
|
def test_view_detail_illegal_import(self):
|
||||||
"""
|
"""
|
||||||
#23601 - Ensure the view exists in the URLconf.
|
#23601 - Ensure the view exists in the URLconf.
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
from django.conf.urls import include, url
|
||||||
|
from django.views import View
|
||||||
|
|
||||||
|
|
||||||
|
def view1(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def view2(request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class View3(View):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
nested = ([
|
||||||
|
url(r'^view1/$', view1, name='view1'),
|
||||||
|
url(r'^view3/$', View3.as_view(), name='view3'),
|
||||||
|
], 'backend')
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^some/path/', include(nested, namespace='nested')),
|
||||||
|
url(r'^view2/$', view2, name='view2'),
|
||||||
|
]
|
|
@ -428,6 +428,13 @@ class ResolverTests(unittest.TestCase):
|
||||||
'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name)
|
'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_namespaced_view_detail(self):
|
||||||
|
resolver = get_resolver('urlpatterns_reverse.nested_urls')
|
||||||
|
self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.view1'))
|
||||||
|
self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.view2'))
|
||||||
|
self.assertTrue(resolver._is_callback('urlpatterns_reverse.nested_urls.View3'))
|
||||||
|
self.assertFalse(resolver._is_callback('urlpatterns_reverse.nested_urls.blub'))
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='urlpatterns_reverse.reverse_lazy_urls')
|
@override_settings(ROOT_URLCONF='urlpatterns_reverse.reverse_lazy_urls')
|
||||||
class ReverseLazyTest(TestCase):
|
class ReverseLazyTest(TestCase):
|
||||||
|
|
Loading…
Reference in New Issue