parent
c40209dcc0
commit
63137a8304
|
@ -79,7 +79,11 @@ class Apps(object):
|
||||||
app_config = entry
|
app_config = entry
|
||||||
else:
|
else:
|
||||||
app_config = AppConfig.create(entry)
|
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
|
self.app_configs[app_config.label] = app_config
|
||||||
|
|
||||||
# Check for duplicate app names.
|
# Check for duplicate app names.
|
||||||
|
|
|
@ -655,6 +655,22 @@ script with::
|
||||||
|
|
||||||
Otherwise, you will hit ``RuntimeError: App registry isn't ready yet.``
|
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
|
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`
|
``handle_app()``. This method receives an :class:`~django.apps.AppConfig`
|
||||||
instance instead of a models module.
|
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
|
Introspecting applications
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@ class NoSuchApp(AppConfig):
|
||||||
name = 'there is no such app'
|
name = 'there is no such app'
|
||||||
|
|
||||||
|
|
||||||
|
class PlainAppsConfig(AppConfig):
|
||||||
|
name = 'apps'
|
||||||
|
|
||||||
|
|
||||||
class RelabeledAppsConfig(AppConfig):
|
class RelabeledAppsConfig(AppConfig):
|
||||||
name = 'apps'
|
name = 'apps'
|
||||||
label = 'relabeled'
|
label = 'relabeled'
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.apps.registry import Apps
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
from .models import TotallyNormal, SoAlternative, new_apps
|
from .models import TotallyNormal, SoAlternative, new_apps
|
||||||
|
|
||||||
|
@ -115,6 +116,16 @@ class AppsTests(TestCase):
|
||||||
def test_relabeling(self):
|
def test_relabeling(self):
|
||||||
self.assertEqual(apps.get_app_config('relabeled').name, 'apps')
|
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):
|
def test_models_py(self):
|
||||||
"""
|
"""
|
||||||
Tests that the models in the models.py file were loaded correctly.
|
Tests that the models in the models.py file were loaded correctly.
|
||||||
|
|
Loading…
Reference in New Issue