From 3e6a3e885336bea43bc42b8fdf8e2401970b7018 Mon Sep 17 00:00:00 2001 From: Manav Agarwal <51242628+manav014@users.noreply.github.com> Date: Fri, 20 Aug 2021 08:54:38 +0200 Subject: [PATCH] Refs #29898 -- Refactored out ProjectState.resolve_model_relations()/resolve_model_field_relations() hooks. --- django/db/migrations/state.py | 51 ++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 6e023415bda..392708134d1 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -346,6 +346,40 @@ class ProjectState: # Render all models self.apps.render_multiple(states_to_be_rendered) + def update_model_field_relation( + self, model, model_key, field_name, field, concretes, + ): + remote_model_key = resolve_relation(model, *model_key) + if remote_model_key[0] not in self.real_apps and remote_model_key in concretes: + remote_model_key = concretes[remote_model_key] + self.relations[remote_model_key][model_key].append((field_name, field)) + + def resolve_model_field_relations( + self, model_key, field_name, field, concretes=None, + ): + remote_field = field.remote_field + if not remote_field: + return + if concretes is None: + concretes, _ = self._get_concrete_models_mapping_and_proxy_models() + + self.update_model_field_relation( + remote_field.model, model_key, field_name, field, concretes, + ) + + through = getattr(remote_field, 'through', None) + if not through: + return + self.update_model_field_relation(through, model_key, field_name, field, concretes) + + def resolve_model_relations(self, model_key, concretes=None): + if concretes is None: + concretes, _ = self._get_concrete_models_mapping_and_proxy_models() + + model_state = self.models[model_key] + for field_name, field in model_state.fields.items(): + self.resolve_model_field_relations(model_key, field_name, field, concretes) + def resolve_fields_and_relations(self): # Resolve fields. for model_state in self.models.values(): @@ -357,23 +391,8 @@ class ProjectState: concretes, proxies = self._get_concrete_models_mapping_and_proxy_models() for model_key in concretes: - model_state = self.models[model_key] - for field_name, field in model_state.fields.items(): - remote_field = field.remote_field - if not remote_field: - continue - remote_model_key = resolve_relation(remote_field.model, *model_key) - if remote_model_key[0] not in self.real_apps and remote_model_key in concretes: - remote_model_key = concretes[remote_model_key] - self.relations[remote_model_key][model_key].append((field_name, field)) + self.resolve_model_relations(model_key, concretes) - through = getattr(remote_field, 'through', None) - if not through: - continue - through_model_key = resolve_relation(through, *model_key) - if through_model_key[0] not in self.real_apps and through_model_key in concretes: - through_model_key = concretes[through_model_key] - self.relations[through_model_key][model_key].append((field_name, field)) for model_key in proxies: self.relations[model_key] = self.relations[concretes[model_key]]