summaryrefslogtreecommitdiff
path: root/django/core
diff options
context:
space:
mode:
authorAndrew Nester <andrew.nester.dev@gmail.com>2016-12-22 00:54:15 +0300
committerTim Graham <timograham@gmail.com>2016-12-21 16:54:15 -0500
commit24fa728a476a6da3e565dbe33959ea62c02c250b (patch)
treebc60bd30f9426d267533c9b5d024858e97dc6d84 /django/core
parent3188b49ee29bb8c7183b55bda784e642a6ec3011 (diff)
Fixed #27612 -- Added a check for duplicate URL instance namespaces.
Diffstat (limited to 'django/core')
-rw-r--r--django/core/checks/urls.py41
1 files changed, 40 insertions, 1 deletions
diff --git a/django/core/checks/urls.py b/django/core/checks/urls.py
index a1e9929084..8187a4e561 100644
--- a/django/core/checks/urls.py
+++ b/django/core/checks/urls.py
@@ -1,9 +1,11 @@
from __future__ import unicode_literals
+from collections import Counter
+
from django.conf import settings
from django.utils import six
-from . import Error, Tags, register
+from . import Error, Tags, Warning, register
@register(Tags.urls)
@@ -28,6 +30,43 @@ def check_resolver(resolver):
return []
+@register(Tags.urls)
+def check_url_namespaces_unique(app_configs, **kwargs):
+ """
+ Warn if URL namespaces used in applications aren't unique.
+ """
+ if not getattr(settings, 'ROOT_URLCONF', None):
+ return []
+
+ from django.urls import get_resolver
+ resolver = get_resolver()
+ all_namespaces = _load_all_namespaces(resolver)
+ counter = Counter(all_namespaces)
+ non_unique_namespaces = [n for n, count in counter.items() if count > 1]
+ errors = []
+ for namespace in non_unique_namespaces:
+ errors.append(Warning(
+ "URL namespace '{}' isn't unique. You may not be able to reverse "
+ "all URLs in this namespace".format(namespace),
+ id="urls.W005",
+ ))
+ return errors
+
+
+def _load_all_namespaces(resolver):
+ """
+ Recursively load all namespaces from URL patterns.
+ """
+ url_patterns = getattr(resolver, 'url_patterns', [])
+ namespaces = [
+ 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))
+ return namespaces
+
+
def get_warning_for_invalid_pattern(pattern):
"""
Return a list containing a warning that the pattern is invalid.