diff --git a/django/db/models/loading.py b/django/db/models/loading.py index e07aab4efe..a1d83cd577 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -131,19 +131,27 @@ class AppCache(object): self._populate() return self.app_errors - def get_models(self, app_mod=None): + def get_models(self, app_mod=None, include_deferred=False): """ Given a module containing models, returns a list of the models. Otherwise returns a list of all installed models. + + 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. """ self._populate() if app_mod: - return self.app_models.get(app_mod.__name__.split('.')[-2], SortedDict()).values() + app_list = [self.app_models.get(app_mod.__name__.split('.')[-2], SortedDict())] else: - model_list = [] - for app_entry in self.app_models.itervalues(): - model_list.extend(app_entry.values()) - return model_list + app_list = self.app_models.itervalues() + model_list = [] + for app in app_list: + model_list.extend( + model for model in app.values() + if (not model._deferred or include_deferred) + ) + return model_list def get_model(self, app_label, model_name, seed_cache=True): """ diff --git a/tests/modeltests/defer/models.py b/tests/modeltests/defer/models.py index 96eb427811..ac3c876a57 100644 --- a/tests/modeltests/defer/models.py +++ b/tests/modeltests/defer/models.py @@ -183,10 +183,4 @@ u"bar" >>> obj.name = "bb" >>> obj.save() -# Finally, we need to flush the app cache for the defer module. -# Using only/defer creates some artifical entries in the app cache -# that messes up later tests. Purge all entries, just to be sure. ->>> from django.db.models.loading import cache ->>> cache.app_models['defer'] = {} - """} diff --git a/tests/regressiontests/defer_regress/models.py b/tests/regressiontests/defer_regress/models.py index a1cd19788d..d9e7bc6249 100644 --- a/tests/regressiontests/defer_regress/models.py +++ b/tests/regressiontests/defer_regress/models.py @@ -132,11 +132,14 @@ False >>> i2._deferred # Item must still be non-deferred False -# Finally, we need to flush the app cache for the defer module. -# Using only/defer creates some artifical entries in the app cache -# that messes up later tests. Purge all entries, just to be sure. ->>> from django.db.models.loading import cache ->>> cache.app_models['defer_regress'] = {} +# Regression for #11936 - loading.get_models should not return deferred models by default. +>>> from django.db.models.loading import get_models +>>> sorted(get_models(models.get_app('defer_regress')), key=lambda obj: obj.__class__.__name__) +[, , , ] + +>>> sorted(get_models(models.get_app('defer_regress'), include_deferred=True), key=lambda obj: obj.__class__.__name__) +[, , , , , , , , , , , ] """ } +