Deprecated the app argument of apps.get_models.

Use app_config.get_models() instead.
This commit is contained in:
Aymeric Augustin 2013-12-29 21:47:55 +01:00
parent e5bcd1d455
commit 34a215d506
5 changed files with 35 additions and 61 deletions

View File

@ -187,40 +187,35 @@ class Apps(object):
def get_models(self, app_mod=None, include_auto_created=False, def get_models(self, app_mod=None, include_auto_created=False,
include_deferred=False, include_swapped=False): include_deferred=False, include_swapped=False):
""" """
Given a module containing models, returns a list of the models. Returns a list of all installed models.
Otherwise returns a list of all installed models.
By default, auto-created models (i.e., m2m models without an By default, the following models aren't included:
explicit intermediate table) are not included. However, if you
specify include_auto_created=True, they will be.
By default, models created to satisfy deferred attribute - auto-created models for many-to-many relations without
queries are *not* included in the list of models. However, if an explicit intermediate table,
you specify include_deferred, they will be. - models created to satisfy deferred attribute queries,
- models that have been swapped out.
By default, models that have been swapped out will *not* be Set the corresponding keyword argument to True to include such models.
included in the list of models. However, if you specify
include_swapped, they will be.
""" """
model_list = None
self.populate_models() self.populate_models()
if app_mod: if app_mod:
warnings.warn(
"The app_mod argument of get_models is deprecated.",
PendingDeprecationWarning, stacklevel=2)
app_label = app_mod.__name__.split('.')[-2] app_label = app_mod.__name__.split('.')[-2]
try: try:
model_dicts = [self.app_configs[app_label].models] return list(self.get_app_config(app_label).get_models(
except KeyError: include_auto_created, include_deferred, include_swapped))
model_dicts = [] except LookupError:
else: return []
model_dicts = [app_config.models for app_config in self.app_configs.values()]
model_list = [] result = []
for model_dict in model_dicts: for app_config in self.app_configs.values():
model_list.extend( result.extend(list(app_config.get_models(
model for model in model_dict.values() include_auto_created, include_deferred, include_swapped)))
if ((not model._deferred or include_deferred) and return result
(not model._meta.auto_created or include_auto_created) and
(not model._meta.swapped or include_swapped))
)
return model_list
def get_model(self, app_label, model_name): def get_model(self, app_label, model_name):
""" """

View File

@ -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 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 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 a private API, obsolete methods and arguments will be removed after a standard
period. In addition, the following changes take effect immediately: deprecation period. In addition, the following changes take effect
immediately:
* ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning * ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning
``None`` when no model is found. ``None`` when no model is found.

View File

@ -79,6 +79,3 @@ class GetModelsTest(TestCase):
self.assertNotIn( self.assertNotIn(
"NotInstalledModel", "NotInstalledModel",
[m.__name__ for m in apps.get_models()]) [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), [])

View File

@ -159,7 +159,7 @@ class AppsTests(TestCase):
""" """
Makes a new model at runtime and ensures it goes into the right place. 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 # Construct a new model in a new app registry
body = {} body = {}
new_apps = Apps() new_apps = Apps()
@ -172,10 +172,7 @@ class AppsTests(TestCase):
body['__module__'] = TotallyNormal.__module__ body['__module__'] = TotallyNormal.__module__
temp_model = type(str("SouthPonies"), (models.Model,), body) temp_model = type(str("SouthPonies"), (models.Model,), body)
# Make sure it appeared in the right place! # Make sure it appeared in the right place!
self.assertEqual( self.assertListEqual(list(apps.get_app_config("apps").get_models()), old_models)
old_models,
apps.get_models(apps.get_app_config("apps").models_module),
)
with self.assertRaises(LookupError): with self.assertRaises(LookupError):
apps.get_model("apps", "SouthPonies") apps.get_model("apps", "SouthPonies")
self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model) self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model)

View File

@ -92,42 +92,26 @@ class DeferRegressionTest(TestCase):
list) list)
def test_ticket_11936(self): def test_ticket_11936(self):
# Regression for #11936 - loading.get_models should not return deferred app_config = apps.get_app_config("defer_regress")
# models by default. # Regression for #11936 - get_models should not return deferred models
# Run a couple of defer queries so that app-cache must contain some # by default. Run a couple of defer queries so that app registry must
# deferred classes. It might contain a lot more classes depending on # contain some deferred classes. It might contain a lot more classes
# the order the tests are ran. # depending on the order the tests are ran.
list(Item.objects.defer("name")) list(Item.objects.defer("name"))
list(Child.objects.defer("value")) list(Child.objects.defer("value"))
klasses = set( klasses = {model.__name__ for model in app_config.get_models()}
map(
attrgetter("__name__"),
apps.get_models(apps.get_app_config("defer_regress").models_module)
)
)
self.assertIn("Child", klasses) self.assertIn("Child", klasses)
self.assertIn("Item", klasses) self.assertIn("Item", klasses)
self.assertNotIn("Child_Deferred_value", klasses) self.assertNotIn("Child_Deferred_value", klasses)
self.assertNotIn("Item_Deferred_name", klasses) self.assertNotIn("Item_Deferred_name", klasses)
self.assertFalse(any( self.assertFalse(any(k._deferred for k in app_config.get_models()))
k._deferred for k in apps.get_models(apps.get_app_config("defer_regress").models_module)))
klasses_with_deferred = set( klasses_with_deferred = {model.__name__ for model in app_config.get_models(include_deferred=True)}
map(
attrgetter("__name__"),
apps.get_models(
apps.get_app_config("defer_regress").models_module, include_deferred=True
),
)
)
self.assertIn("Child", klasses_with_deferred) self.assertIn("Child", klasses_with_deferred)
self.assertIn("Item", klasses_with_deferred) self.assertIn("Item", klasses_with_deferred)
self.assertIn("Child_Deferred_value", klasses_with_deferred) self.assertIn("Child_Deferred_value", klasses_with_deferred)
self.assertIn("Item_Deferred_name", klasses_with_deferred) self.assertIn("Item_Deferred_name", klasses_with_deferred)
self.assertTrue(any( self.assertTrue(any(k._deferred for k in app_config.get_models(include_deferred=True)))
k._deferred for k in apps.get_models(
apps.get_app_config("defer_regress").models_module, include_deferred=True))
)
@override_settings(SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer') @override_settings(SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer')
def test_ticket_12163(self): def test_ticket_12163(self):