Permalink
Browse files

Enforced unicity of app labels.

Fixed #21679.
  • Loading branch information...
1 parent c40209d commit 63137a8304d4387132e749c97aad1049526f601c @aaugustin aaugustin committed Dec 31, 2013
Showing with 36 additions and 8 deletions.
  1. +5 −1 django/apps/registry.py
  2. +16 −7 docs/releases/1.7.txt
  3. +4 −0 tests/apps/apps.py
  4. +11 −0 tests/apps/tests.py
View
@@ -79,7 +79,11 @@ def populate(self, installed_apps=None):
app_config = entry
else:
app_config = AppConfig.create(entry)
- # TODO: check for duplicate app labels here (#21679).
+ if app_config.label in self.app_configs:
+ raise ImproperlyConfigured(
+ "Application labels aren't unique, "
+ "duplicates: %s" % app_config.label)
+
self.app_configs[app_config.label] = app_config
# Check for duplicate app names.
View
@@ -655,6 +655,22 @@ script with::
Otherwise, you will hit ``RuntimeError: App registry isn't ready yet.``
+App registry consistency
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+It is no longer possible to have multiple installed applications with the same
+label. In previous versions of Django, this didn't always work correctly, but
+didn't crash outright either.
+
+If you have two apps with the same label, you should create an
+:class:`~django.apps.AppConfig` for one of them and override its
+:class:`~django.apps.AppConfig.label` there. You should then adjust your code
+wherever it references this application or its models with the old label.
+
+You should make sure that your project doesn't import models from applications
+that aren't in :setting:`INSTALLED_APPS`. Relations involving such models may
+not be created properly. Future versions of Django may forbid this entirely.
+
Subclassing AppCommand
^^^^^^^^^^^^^^^^^^^^^^
@@ -663,13 +679,6 @@ Subclasses of :class:`~django.core.management.AppCommand` must now implement a
``handle_app()``. This method receives an :class:`~django.apps.AppConfig`
instance instead of a models module.
-App registry consistency
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-You should make sure that your project doesn't import models from applications
-that aren't in :setting:`INSTALLED_APPS`. Relations involving such models may
-not be created properly.
-
Introspecting applications
^^^^^^^^^^^^^^^^^^^^^^^^^^
View
@@ -25,6 +25,10 @@ class NoSuchApp(AppConfig):
name = 'there is no such app'
+class PlainAppsConfig(AppConfig):
+ name = 'apps'
+
+
class RelabeledAppsConfig(AppConfig):
name = 'apps'
label = 'relabeled'
View
@@ -5,6 +5,7 @@
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.test import TestCase, override_settings
+from django.utils import six
from .models import TotallyNormal, SoAlternative, new_apps
@@ -115,6 +116,16 @@ def test_has_app(self):
def test_relabeling(self):
self.assertEqual(apps.get_app_config('relabeled').name, 'apps')
+ def test_duplicate_labels(self):
+ with six.assertRaisesRegex(self, ImproperlyConfigured, "Application labels aren't unique"):
+ with self.settings(INSTALLED_APPS=['apps.apps.PlainAppsConfig', 'apps']):
+ pass
+
+ def test_duplicate_names(self):
+ with six.assertRaisesRegex(self, ImproperlyConfigured, "Application names aren't unique"):
+ with self.settings(INSTALLED_APPS=['apps.apps.RelabeledAppsConfig', 'apps']):
+ pass
+
def test_models_py(self):
"""
Tests that the models in the models.py file were loaded correctly.

0 comments on commit 63137a8

Please sign in to comment.