MCPcopy
hub / github.com/django/django / ProjectState

Class ProjectState

django/db/migrations/state.py:95–604  ·  view source on GitHub ↗

Represent the entire project's overall state. This is the item that is passed around - do it here rather than at the app level so that cross-app FKs/etc. resolve properly.

Source from the content-addressed store, hash-verified

93
94
95class ProjectState:
96 """
97 Represent the entire project's overall state. This is the item that is
98 passed around - do it here rather than at the app level so that cross-app
99 FKs/etc. resolve properly.
100 """
101
102 def __init__(self, models=None, real_apps=None):
103 self.models = models or {}
104 # Apps to include from main registry, usually unmigrated ones
105 if real_apps is None:
106 real_apps = set()
107 else:
108 assert isinstance(real_apps, set)
109 self.real_apps = real_apps
110 self.is_delayed = False
111 # {remote_model_key: {model_key: {field_name: field}}}
112 self._relations = None
113
114 @property
115 def relations(self):
116 if self._relations is None:
117 self.resolve_fields_and_relations()
118 return self._relations
119
120 def add_model(self, model_state):
121 model_key = model_state.app_label, model_state.name_lower
122 self.models[model_key] = model_state
123 if self._relations is not None:
124 self.resolve_model_relations(model_key)
125 if "apps" in self.__dict__: # hasattr would cache the property
126 self.reload_model(*model_key)
127
128 def remove_model(self, app_label, model_name):
129 model_key = app_label, model_name
130 del self.models[model_key]
131 if self._relations is not None:
132 self._relations.pop(model_key, None)
133 # Call list() since _relations can change size during iteration.
134 for related_model_key, model_relations in list(self._relations.items()):
135 model_relations.pop(model_key, None)
136 if not model_relations:
137 del self._relations[related_model_key]
138 if "apps" in self.__dict__: # hasattr would cache the property
139 self.apps.unregister_model(*model_key)
140 # Need to do this explicitly since unregister_model() doesn't clear
141 # the cache automatically (#24513)
142 self.apps.clear_cache()
143
144 def rename_model(self, app_label, old_name, new_name):
145 # Add a new model.
146 old_name_lower = old_name.lower()
147 new_name_lower = new_name.lower()
148 renamed_model = self.models[app_label, old_name_lower].clone()
149 renamed_model.name = new_name
150 self.models[app_label, new_name_lower] = renamed_model
151 # Repoint all fields pointing to the old model to the new one.
152 old_model_tuple = (app_label, old_name_lower)

Calls

no outgoing calls