Commit 888c9b64 authored by Marten Kenbeek's avatar Marten Kenbeek Committed by Markus Holtermann
Browse files

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.
parent 180f75c2
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -326,7 +326,10 @@ 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):
            # 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()


+7 −0
Original line number Diff line number Diff line
@@ -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):
        """