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.
This commit is contained in:
Marten Kenbeek 2015-02-22 04:26:17 +01:00 committed by Markus Holtermann
parent 180f75c2a0
commit 888c9b6429
2 changed files with 12 additions and 2 deletions

View File

@ -326,8 +326,11 @@ class Apps(object):
# the relation tree and the fields cache. # the relation tree and the fields cache.
self.get_models.cache_clear() self.get_models.cache_clear()
if self.ready: if self.ready:
for model in self.get_models(include_auto_created=True): # Circumvent self.get_models() to prevent that the cache is refilled.
model._meta._expire_cache() # 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) apps = Apps(installed_apps=None)

View File

@ -236,6 +236,10 @@ class StateApps(Apps):
# base errors, until the size of the unrendered models doesn't # base errors, until the size of the unrendered models doesn't
# decrease by at least one, meaning there's a base dependency loop/ # decrease by at least one, meaning there's a base dependency loop/
# missing base. # missing base.
if not model_states:
return
# Prevent that all model caches are expired for each render.
self.ready = False
unrendered_models = model_states unrendered_models = model_states
while unrendered_models: while unrendered_models:
new_unrendered_models = [] new_unrendered_models = []
@ -245,6 +249,7 @@ class StateApps(Apps):
except InvalidBasesError: except InvalidBasesError:
new_unrendered_models.append(model) new_unrendered_models.append(model)
if len(new_unrendered_models) == len(unrendered_models): if len(new_unrendered_models) == len(unrendered_models):
self.ready = True
raise InvalidBasesError( raise InvalidBasesError(
"Cannot resolve bases for %r\nThis can happen if you are inheriting models from an " "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 " "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()) "for more" % (new_unrendered_models, get_docs_version())
) )
unrendered_models = new_unrendered_models unrendered_models = new_unrendered_models
self.ready = True
self.clear_cache()
def clone(self): def clone(self):
""" """