From 888c9b6429a44824078a49fb1ebacf2e950cd887 Mon Sep 17 00:00:00 2001 From: Marten Kenbeek Date: Sun, 22 Feb 2015 04:26:17 +0100 Subject: [PATCH] Fixed #24397 -- Sped up rendering multiple model states. Set apps.ready to False when rendering multiple models. This prevents that the cache on Model._meta is expired on all models after each time a single model is rendered. Prevented that Apps.clear_cache() refills the cache on Apps.get_models(), so that the wrong value cannot be cached when cloning a StateApps. --- django/apps/registry.py | 7 +++++-- django/db/migrations/state.py | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/django/apps/registry.py b/django/apps/registry.py index e75bb99cfe..164427d85f 100644 --- a/django/apps/registry.py +++ b/django/apps/registry.py @@ -326,8 +326,11 @@ class Apps(object): # the relation tree and the fields cache. self.get_models.cache_clear() if self.ready: - for model in self.get_models(include_auto_created=True): - model._meta._expire_cache() + # Circumvent self.get_models() to prevent that the cache is refilled. + # This particularly prevents that an empty value is cached while cloning. + for app_config in self.app_configs.values(): + for model in app_config.get_models(include_auto_created=True): + model._meta._expire_cache() apps = Apps(installed_apps=None) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 7c5f9ed776..3d78cf609e 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -236,6 +236,10 @@ class StateApps(Apps): # base errors, until the size of the unrendered models doesn't # decrease by at least one, meaning there's a base dependency loop/ # missing base. + if not model_states: + return + # Prevent that all model caches are expired for each render. + self.ready = False unrendered_models = model_states while unrendered_models: new_unrendered_models = [] @@ -245,6 +249,7 @@ class StateApps(Apps): except InvalidBasesError: new_unrendered_models.append(model) if len(new_unrendered_models) == len(unrendered_models): + self.ready = True raise InvalidBasesError( "Cannot resolve bases for %r\nThis can happen if you are inheriting models from an " "app with migrations (e.g. contrib.auth)\n in an app with no migrations; see " @@ -252,6 +257,8 @@ class StateApps(Apps): "for more" % (new_unrendered_models, get_docs_version()) ) unrendered_models = new_unrendered_models + self.ready = True + self.clear_cache() def clone(self): """