diff options
| author | David Wobrock <david.wobrock@gmail.com> | 2021-10-16 11:20:33 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-10-25 10:45:35 +0200 |
| commit | ea00a0843eb7a7bb074625a663ca4f5c86b8c5bd (patch) | |
| tree | b3fb925bf40e5ace19eefa8dc09941e60054e2b7 /django | |
| parent | c9ebe4ca4e3f5d5d76bfbdae489e3f44e32416e5 (diff) | |
[4.0.x] Fixed #31503 -- Made autodetector remove unique/index_together before altering fields.
Backport of 0314593fe8e7dc685bbb6585eee40e755588864e from main
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/migrations/autodetector.py | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 594658ce99..96cb463848 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -178,8 +178,12 @@ class MigrationAutodetector: # Generate index removal operations before field is removed self.generate_removed_constraints() self.generate_removed_indexes() - # Generate field operations + # Generate field renaming operations. self.generate_renamed_fields() + # Generate removal of foo together. + self.generate_removed_altered_unique_together() + self.generate_removed_altered_index_together() + # Generate field operations. self.generate_removed_fields() self.generate_added_fields() self.generate_altered_fields() @@ -1105,8 +1109,7 @@ class MigrationAutodetector: dependencies.append((through_app_label, through_object_name, None, True)) return dependencies - def _generate_altered_foo_together(self, operation): - option_name = operation.option_name + def _get_altered_foo_together_operations(self, option_name): for app_label, model_name in sorted(self.kept_model_keys): old_model_name = self.renamed_models.get((app_label, model_name), model_name) old_model_state = self.from_state.models[app_label, old_model_name] @@ -1134,13 +1137,49 @@ class MigrationAutodetector: dependencies.extend(self._get_dependencies_for_foreign_key( app_label, model_name, field, self.to_state, )) + yield ( + old_value, + new_value, + app_label, + model_name, + dependencies, + ) + def _generate_removed_altered_foo_together(self, operation): + for ( + old_value, + new_value, + app_label, + model_name, + dependencies, + ) in self._get_altered_foo_together_operations(operation.option_name): + removal_value = new_value.intersection(old_value) + if removal_value or old_value: self.add_operation( app_label, - operation( - name=model_name, - **{option_name: new_value} - ), + operation(name=model_name, **{operation.option_name: removal_value}), + dependencies=dependencies, + ) + + def generate_removed_altered_unique_together(self): + self._generate_removed_altered_foo_together(operations.AlterUniqueTogether) + + def generate_removed_altered_index_together(self): + self._generate_removed_altered_foo_together(operations.AlterIndexTogether) + + def _generate_altered_foo_together(self, operation): + for ( + old_value, + new_value, + app_label, + model_name, + dependencies, + ) in self._get_altered_foo_together_operations(operation.option_name): + removal_value = new_value.intersection(old_value) + if new_value != removal_value: + self.add_operation( + app_label, + operation(name=model_name, **{operation.option_name: new_value}), dependencies=dependencies, ) |
