1
0
mirror of https://github.com/django/django.git synced 2025-10-26 07:06:08 +00:00

Moved list of models inside AppConfig instances.

This commit is a refactoring with no change of functionality, according
to the following invariants:

- An app_label that was in app_configs and app_models stays in
  app_config and has its 'installed' attribute set to True.

- An app_label that was in app_models but not in app_configs is added to
  app_configs and has its 'installed' attribute set to True.

As a consequence, all the code that iterated on app_configs is modified
to check for the 'installed' attribute. Code that iterated on app_models
is rewritten in terms of app_configs.

Many tests that stored and restored the state of the app cache were
updated.

In the long term, we should reconsider the usefulness of allowing
importing models from non-installed applications. This doesn't sound
particularly useful, can be a trap in some circumstances, and causes
significant complexity in sensitive areas of Django.
This commit is contained in:
Aymeric Augustin
2013-12-12 21:34:39 +01:00
parent 2c9e84af4a
commit b55282b98b
10 changed files with 87 additions and 73 deletions

View File

@@ -1,6 +1,5 @@
from __future__ import unicode_literals
import copy
import os
import sys
from unittest import TestCase
@@ -17,14 +16,15 @@ class EggLoadingTest(TestCase):
self.old_path = sys.path[:]
self.egg_dir = '%s/eggs' % os.path.dirname(upath(__file__))
# This test adds dummy applications to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
self.old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
self._old_models = app_cache.app_configs['app_loading'].models.copy()
def tearDown(self):
app_cache.app_configs['app_loading'].models = self._old_models
app_cache._get_models_cache = {}
sys.path = self.old_path
app_cache.app_models = self.old_app_models
def test_egg1(self):
"""Models module can be loaded from an app in an egg"""

View File

@@ -1,4 +1,3 @@
import copy
import sys
import unittest
@@ -19,13 +18,12 @@ class InvalidModelTestCase(unittest.TestCase):
self.stdout = StringIO()
sys.stdout = self.stdout
# This test adds dummy applications to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
self.old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
self._old_models = app_cache.app_configs['invalid_models'].models.copy()
def tearDown(self):
app_cache.app_models = self.old_app_models
app_cache.app_configs['invalid_models'].models = self._old_models
app_cache._get_models_cache = {}
sys.stdout = self.old_stdout

View File

@@ -1,5 +1,4 @@
from __future__ import unicode_literals
import copy
from django.apps import app_cache
from django.db import models
@@ -110,12 +109,11 @@ class ManagersRegressionTests(TestCase):
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
_old_models = app_cache.app_configs['managers_regress'].models.copy()
try:
class SwappableModel(models.Model):
class Meta:
swappable = 'TEST_SWAPPABLE_MODEL'
@@ -129,16 +127,16 @@ class ManagersRegressionTests(TestCase):
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
app_cache.app_configs['managers_regress'].models = _old_models
app_cache._get_models_cache = {}
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_custom_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
_old_models = app_cache.app_configs['managers_regress'].models.copy()
try:
class SwappableModel(models.Model):
stuff = models.Manager()
@@ -156,16 +154,16 @@ class ManagersRegressionTests(TestCase):
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
app_cache.app_configs['managers_regress'].models = _old_models
app_cache._get_models_cache = {}
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_explicit_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
_old_models = app_cache.app_configs['managers_regress'].models.copy()
try:
class SwappableModel(models.Model):
objects = models.Manager()
@@ -183,7 +181,8 @@ class ManagersRegressionTests(TestCase):
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
app_cache.app_configs['managers_regress'].models = _old_models
app_cache._get_models_cache = {}
def test_regress_3871(self):
related = RelatedModel.objects.create()

View File

@@ -2,7 +2,6 @@
from __future__ import unicode_literals
import codecs
import copy
import os
import shutil
@@ -132,10 +131,10 @@ class MakeMigrationsTests(MigrationTestBase):
self.test_dir = os.path.abspath(os.path.dirname(upath(__file__)))
self.migration_dir = os.path.join(self.test_dir, 'migrations_%d' % self.creation_counter)
self.migration_pkg = "migrations.migrations_%d" % self.creation_counter
self._old_app_models = copy.deepcopy(app_cache.app_models)
self._old_models = app_cache.app_configs['migrations'].models.copy()
def tearDown(self):
app_cache.app_models = self._old_app_models
app_cache.app_configs['migrations'].models = self._old_models
app_cache._get_models_cache = {}
os.chdir(self.test_dir)

View File

@@ -1,5 +1,4 @@
import unittest
from django.apps import app_cache
from django.db import connection, models, migrations, router
from django.db.models.fields import NOT_PROVIDED
from django.db.transaction import atomic

View File

@@ -34,8 +34,6 @@ class ProxyModelInheritanceTests(TransactionTestCase):
sys.path = self.old_sys_path
del app_cache.app_configs['app1']
del app_cache.app_configs['app2']
del app_cache.app_models['app1']
del app_cache.app_models['app2']
def test_table_exists(self):
try:

View File

@@ -1,5 +1,4 @@
from __future__ import unicode_literals
import copy
from django.apps import app_cache
from django.contrib import admin
@@ -155,12 +154,11 @@ class ProxyModelTests(TestCase):
@override_settings(TEST_SWAPPABLE_MODEL='proxy_models.AlternateModel')
def test_swappable(self):
try:
# This test adds dummy applications to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
# The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests.
_old_models = app_cache.app_configs['proxy_models'].models.copy()
try:
class SwappableModel(models.Model):
class Meta:
@@ -176,7 +174,8 @@ class ProxyModelTests(TestCase):
class Meta:
proxy = True
finally:
app_cache.app_models = old_app_models
app_cache.app_configs['proxy_models'].models = _old_models
app_cache._get_models_cache = {}
def test_myperson_manager(self):
Person.objects.create(name="fred")

View File

@@ -1,7 +1,5 @@
from __future__ import unicode_literals
import copy
from django.apps import app_cache
from django.conf import settings
from django.db import connection
@@ -28,7 +26,7 @@ class TablespacesTests(TestCase):
def setUp(self):
# The unmanaged models need to be removed after the test in order to
# prevent bad interactions with the flush operation in other tests.
self.old_app_models = copy.deepcopy(app_cache.app_models)
self._old_models = app_cache.app_configs['tablespaces'].models.copy()
for model in Article, Authors, Reviewers, Scientist:
model._meta.managed = True
@@ -37,7 +35,7 @@ class TablespacesTests(TestCase):
for model in Article, Authors, Reviewers, Scientist:
model._meta.managed = False
app_cache.app_models = self.old_app_models
app_cache.app_configs['tablespaces'].models = self._old_models
app_cache._get_models_cache = {}
def assertNumContains(self, haystack, needle, count):