Loading django/apps/registry.py +5 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,11 @@ class Apps(object): 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. Loading docs/releases/1.7.txt +16 −7 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^^^^^^^^^^^^^^^^^ Loading @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading tests/apps/apps.py +4 −0 Original line number Diff line number Diff line Loading @@ -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' tests/apps/tests.py +11 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from django.apps.registry import Apps 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 Loading Loading @@ -115,6 +116,16 @@ class AppsTests(TestCase): 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. Loading Loading
django/apps/registry.py +5 −1 Original line number Diff line number Diff line Loading @@ -79,7 +79,11 @@ class Apps(object): 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. Loading
docs/releases/1.7.txt +16 −7 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^^^^^^^^^^^^^^^^^ Loading @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading
tests/apps/apps.py +4 −0 Original line number Diff line number Diff line Loading @@ -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'
tests/apps/tests.py +11 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ from django.apps.registry import Apps 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 Loading Loading @@ -115,6 +116,16 @@ class AppsTests(TestCase): 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. Loading