diff options
-rw-r--r-- | django/db/migrations/autodetector.py | 20 | ||||
-rw-r--r-- | tests/migrations/test_autodetector.py | 59 |
2 files changed, 79 insertions, 0 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 5a5f5a14fb..23c97e5474 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -1304,6 +1304,7 @@ class MigrationAutodetector: def generate_added_indexes(self): for (app_label, model_name), alt_indexes in self.altered_indexes.items(): + dependencies = self._get_dependencies_for_model(app_label, model_name) for index in alt_indexes["added_indexes"]: self.add_operation( app_label, @@ -1311,6 +1312,7 @@ class MigrationAutodetector: model_name=model_name, index=index, ), + dependencies=dependencies, ) def generate_removed_indexes(self): @@ -1367,6 +1369,7 @@ class MigrationAutodetector: app_label, model_name, ), alt_constraints in self.altered_constraints.items(): + dependencies = self._get_dependencies_for_model(app_label, model_name) for constraint in alt_constraints["added_constraints"]: self.add_operation( app_label, @@ -1374,6 +1377,7 @@ class MigrationAutodetector: model_name=model_name, constraint=constraint, ), + dependencies=dependencies, ) def generate_removed_constraints(self): @@ -1425,6 +1429,22 @@ class MigrationAutodetector: dependencies.append((through_app_label, through_object_name, None, True)) return dependencies + def _get_dependencies_for_model(self, app_label, model_name): + """Return foreign key dependencies of the given model.""" + dependencies = [] + model_state = self.to_state.models[app_label, model_name] + for field in model_state.fields.values(): + if field.is_relation: + dependencies.extend( + self._get_dependencies_for_foreign_key( + app_label, + model_name, + field, + self.to_state, + ) + ) + return dependencies + 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( diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 6422c82214..44923a3c2e 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -2720,6 +2720,65 @@ class AutodetectorTests(BaseAutodetectorTests): changes, "testapp", 0, 0, model_name="author", constraint=added_constraint ) + def test_add_constraints_with_new_model(self): + book_with_unique_title_and_pony = ModelState( + "otherapp", + "Book", + [ + ("id", models.AutoField(primary_key=True)), + ("title", models.CharField(max_length=200)), + ("pony", models.ForeignKey("otherapp.Pony", models.CASCADE)), + ], + { + "constraints": [ + models.UniqueConstraint( + fields=["title", "pony"], + name="unique_title_pony", + ) + ] + }, + ) + changes = self.get_changes( + [self.book_with_no_author], + [book_with_unique_title_and_pony, self.other_pony], + ) + + self.assertNumberMigrations(changes, "otherapp", 1) + self.assertOperationTypes( + changes, + "otherapp", + 0, + ["CreateModel", "AddField", "AddConstraint"], + ) + + def test_add_index_with_new_model(self): + book_with_index_title_and_pony = ModelState( + "otherapp", + "Book", + [ + ("id", models.AutoField(primary_key=True)), + ("title", models.CharField(max_length=200)), + ("pony", models.ForeignKey("otherapp.Pony", models.CASCADE)), + ], + { + "indexes": [ + models.Index(fields=["title", "pony"], name="index_title_pony"), + ] + }, + ) + changes = self.get_changes( + [self.book_with_no_author], + [book_with_index_title_and_pony, self.other_pony], + ) + + self.assertNumberMigrations(changes, "otherapp", 1) + self.assertOperationTypes( + changes, + "otherapp", + 0, + ["CreateModel", "AddField", "AddIndex"], + ) + def test_remove_constraints(self): """Test change detection of removed constraints.""" changes = self.get_changes( |