diff --git a/django/db/models/loading.py b/django/db/models/loading.py index 6fab4a931b..2c35fdb1df 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -159,7 +159,8 @@ class AppCache(object): return self.app_errors def get_models(self, app_mod=None, - include_auto_created=False, include_deferred=False): + include_auto_created=False, include_deferred=False, + only_installed=True): """ Given a module containing models, returns a list of the models. Otherwise returns a list of all installed models. @@ -172,7 +173,7 @@ class AppCache(object): queries are *not* included in the list of models. However, if you specify include_deferred, they will be. """ - cache_key = (app_mod, include_auto_created, include_deferred) + cache_key = (app_mod, include_auto_created, include_deferred, only_installed) try: return self._get_models_cache[cache_key] except KeyError: @@ -185,8 +186,11 @@ class AppCache(object): else: app_list = [] else: - app_list = [self.app_models.get(app_label, SortedDict()) - for app_label in self.app_labels.iterkeys()] + if only_installed: + app_list = [self.app_models.get(app_label, SortedDict()) + for app_label in self.app_labels.iterkeys()] + else: + app_list = self.app_models.itervalues() model_list = [] for app in app_list: model_list.extend( diff --git a/django/db/models/options.py b/django/db/models/options.py index 6d8ab6f6d6..15cb18b133 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -383,7 +383,7 @@ class Options(object): cache[obj] = parent else: cache[obj] = model - for klass in get_models(include_auto_created=True): + for klass in get_models(include_auto_created=True, only_installed=False): for f in klass._meta.local_fields: if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta: cache[RelatedObject(f.rel.to, klass, f)] = None diff --git a/tests/regressiontests/app_loading/not_installed/models.py b/tests/regressiontests/app_loading/not_installed/models.py index 615feefddb..f62235dfd5 100644 --- a/tests/regressiontests/app_loading/not_installed/models.py +++ b/tests/regressiontests/app_loading/not_installed/models.py @@ -3,3 +3,7 @@ from django.db import models class NotInstalledModel(models.Model): pass + + +class RelatedModel(models.Model): + not_installed = models.ForeignKey(NotInstalledModel) diff --git a/tests/regressiontests/app_loading/tests.py b/tests/regressiontests/app_loading/tests.py index 6ee06c50c9..3036ab8c07 100644 --- a/tests/regressiontests/app_loading/tests.py +++ b/tests/regressiontests/app_loading/tests.py @@ -85,8 +85,8 @@ class EggLoadingTest(TestCase): class GetModelsTest(TestCase): def setUp(self): - import not_installed.models - self.not_installed_module = not_installed.models + from .not_installed import models + self.not_installed_module = models def test_get_model_only_returns_installed_models(self): @@ -94,6 +94,13 @@ class GetModelsTest(TestCase): get_model("not_installed", "NotInstalledModel"), None) + def test_get_model_with_not_installed(self): + self.assertEqual( + get_model( + "not_installed", "NotInstalledModel", only_installed=False), + self.not_installed_module.NotInstalledModel) + + def test_get_models_only_returns_installed_models(self): self.assertFalse( "NotInstalledModel" in @@ -102,3 +109,17 @@ class GetModelsTest(TestCase): def test_get_models_with_app_label_only_returns_installed_models(self): self.assertEqual(get_models(self.not_installed_module), []) + + + def test_get_models_with_not_installed(self): + self.assertTrue( + "NotInstalledModel" in [ + m.__name__ for m in get_models(only_installed=False)]) + + +class NotInstalledModelsTest(TestCase): + def test_related_not_installed_model(self): + from .not_installed.models import NotInstalledModel + self.assertEqual( + set(NotInstalledModel._meta.get_all_field_names()), + set(["id", "relatedmodel"]))