diff --git a/django/apps/registry.py b/django/apps/registry.py index d8265ce4d21..5dbb4696d75 100644 --- a/django/apps/registry.py +++ b/django/apps/registry.py @@ -187,40 +187,35 @@ class Apps(object): def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False, include_swapped=False): """ - Given a module containing models, returns a list of the models. - Otherwise returns a list of all installed models. + Returns a list of all installed models. - By default, auto-created models (i.e., m2m models without an - explicit intermediate table) are not included. However, if you - specify include_auto_created=True, they will be. + By default, the following models aren't included: - By default, models created to satisfy deferred attribute - queries are *not* included in the list of models. However, if - you specify include_deferred, they will be. + - auto-created models for many-to-many relations without + an explicit intermediate table, + - models created to satisfy deferred attribute queries, + - models that have been swapped out. - By default, models that have been swapped out will *not* be - included in the list of models. However, if you specify - include_swapped, they will be. + Set the corresponding keyword argument to True to include such models. """ - model_list = None self.populate_models() + if app_mod: + warnings.warn( + "The app_mod argument of get_models is deprecated.", + PendingDeprecationWarning, stacklevel=2) app_label = app_mod.__name__.split('.')[-2] try: - model_dicts = [self.app_configs[app_label].models] - except KeyError: - model_dicts = [] - else: - model_dicts = [app_config.models for app_config in self.app_configs.values()] - model_list = [] - for model_dict in model_dicts: - model_list.extend( - model for model in model_dict.values() - if ((not model._deferred or include_deferred) and - (not model._meta.auto_created or include_auto_created) and - (not model._meta.swapped or include_swapped)) - ) - return model_list + return list(self.get_app_config(app_label).get_models( + include_auto_created, include_deferred, include_swapped)) + except LookupError: + return [] + + result = [] + for app_config in self.app_configs.values(): + result.extend(list(app_config.get_models( + include_auto_created, include_deferred, include_swapped))) + return result def get_model(self, app_label, model_name): """ diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 5416d9dc0ba..b4ee180c73e 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -615,8 +615,9 @@ setting directly and use the app registry (:attr:`django.apps.apps`) instead. The "app registry" that manages the list of installed applications doesn't have the same features as the old "app cache". Even though the "app cache" was -a private API, obsolete methods will be removed after a standard deprecation -period. In addition, the following changes take effect immediately: +a private API, obsolete methods and arguments will be removed after a standard +deprecation period. In addition, the following changes take effect +immediately: * ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning ``None`` when no model is found. diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py index 5219b5315d7..46c5955c53c 100644 --- a/tests/app_loading/tests.py +++ b/tests/app_loading/tests.py @@ -79,6 +79,3 @@ class GetModelsTest(TestCase): self.assertNotIn( "NotInstalledModel", [m.__name__ for m in apps.get_models()]) - - def test_get_models_with_app_label_only_returns_installed_models(self): - self.assertEqual(apps.get_models(self.not_installed_module), []) diff --git a/tests/apps/tests.py b/tests/apps/tests.py index 4cd35c38cfd..a75ae94a753 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -159,7 +159,7 @@ class AppsTests(TestCase): """ Makes a new model at runtime and ensures it goes into the right place. """ - old_models = apps.get_models(apps.get_app_config("apps").models_module) + old_models = list(apps.get_app_config("apps").get_models()) # Construct a new model in a new app registry body = {} new_apps = Apps() @@ -172,10 +172,7 @@ class AppsTests(TestCase): body['__module__'] = TotallyNormal.__module__ temp_model = type(str("SouthPonies"), (models.Model,), body) # Make sure it appeared in the right place! - self.assertEqual( - old_models, - apps.get_models(apps.get_app_config("apps").models_module), - ) + self.assertListEqual(list(apps.get_app_config("apps").get_models()), old_models) with self.assertRaises(LookupError): apps.get_model("apps", "SouthPonies") self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model) diff --git a/tests/defer_regress/tests.py b/tests/defer_regress/tests.py index 22c2d281daa..97d7e7e3021 100644 --- a/tests/defer_regress/tests.py +++ b/tests/defer_regress/tests.py @@ -92,42 +92,26 @@ class DeferRegressionTest(TestCase): list) def test_ticket_11936(self): - # Regression for #11936 - loading.get_models should not return deferred - # models by default. - # Run a couple of defer queries so that app-cache must contain some - # deferred classes. It might contain a lot more classes depending on - # the order the tests are ran. + app_config = apps.get_app_config("defer_regress") + # Regression for #11936 - get_models should not return deferred models + # by default. Run a couple of defer queries so that app registry must + # contain some deferred classes. It might contain a lot more classes + # depending on the order the tests are ran. list(Item.objects.defer("name")) list(Child.objects.defer("value")) - klasses = set( - map( - attrgetter("__name__"), - apps.get_models(apps.get_app_config("defer_regress").models_module) - ) - ) + klasses = {model.__name__ for model in app_config.get_models()} self.assertIn("Child", klasses) self.assertIn("Item", klasses) self.assertNotIn("Child_Deferred_value", klasses) self.assertNotIn("Item_Deferred_name", klasses) - self.assertFalse(any( - k._deferred for k in apps.get_models(apps.get_app_config("defer_regress").models_module))) + self.assertFalse(any(k._deferred for k in app_config.get_models())) - klasses_with_deferred = set( - map( - attrgetter("__name__"), - apps.get_models( - apps.get_app_config("defer_regress").models_module, include_deferred=True - ), - ) - ) + klasses_with_deferred = {model.__name__ for model in app_config.get_models(include_deferred=True)} self.assertIn("Child", klasses_with_deferred) self.assertIn("Item", klasses_with_deferred) self.assertIn("Child_Deferred_value", klasses_with_deferred) self.assertIn("Item_Deferred_name", klasses_with_deferred) - self.assertTrue(any( - k._deferred for k in apps.get_models( - apps.get_app_config("defer_regress").models_module, include_deferred=True)) - ) + self.assertTrue(any(k._deferred for k in app_config.get_models(include_deferred=True))) @override_settings(SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer') def test_ticket_12163(self):