diff --git a/django/core/checks/urls.py b/django/core/checks/urls.py index c39010fb7d..13c7e2b08b 100644 --- a/django/core/checks/urls.py +++ b/django/core/checks/urls.py @@ -50,17 +50,18 @@ def check_url_namespaces_unique(app_configs, **kwargs): return errors -def _load_all_namespaces(resolver): +def _load_all_namespaces(resolver, parents=()): """ Recursively load all namespaces from URL patterns. """ url_patterns = getattr(resolver, 'url_patterns', []) namespaces = [ - url.namespace for url in url_patterns + ':'.join(parents + (url.namespace,)) for url in url_patterns if getattr(url, 'namespace', None) is not None ] for pattern in url_patterns: - namespaces.extend(_load_all_namespaces(pattern)) + current = parents + (getattr(pattern, 'namespace', ()),) + namespaces.extend(_load_all_namespaces(pattern, current)) return namespaces diff --git a/tests/check_framework/urls/unique_namespaces.py b/tests/check_framework/urls/unique_namespaces.py index 897f27757e..10d427eec9 100644 --- a/tests/check_framework/urls/unique_namespaces.py +++ b/tests/check_framework/urls/unique_namespaces.py @@ -5,7 +5,14 @@ common_url_patterns = ([ url(r'^app-url/', include([])), ], 'common') +nested_url_patterns = ([ + url(r'^common/', include(common_url_patterns, namespace='nested')), +], 'nested') + urlpatterns = [ url(r'^app-ns1-0/', include(common_url_patterns, namespace='app-include-1')), - url(r'^app-ns1-1/', include(common_url_patterns, namespace='app-include-2')) + url(r'^app-ns1-1/', include(common_url_patterns, namespace='app-include-2')), + # 'nested' is included twice but namespaced by nested-1 and nested-2. + url(r'^app-ns1-2/', include(nested_url_patterns, namespace='nested-1')), + url(r'^app-ns1-3/', include(nested_url_patterns, namespace='nested-2')), ]