summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/migrations/autodetector.py5
-rw-r--r--tests/migrations/test_autodetector.py50
2 files changed, 49 insertions, 6 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index 5f41053283..4bcbae8bd3 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -1022,8 +1022,9 @@ class MigrationAutodetector:
def _generate_added_field(self, app_label, model_name, field_name):
field = self.to_state.models[app_label, model_name].get_field(field_name)
- # Fields that are foreignkeys/m2ms depend on stuff
- dependencies = []
+ # Adding a field always depends at least on its removal.
+ dependencies = [(app_label, model_name, field_name, False)]
+ # Fields that are foreignkeys/m2ms depend on stuff.
if field.remote_field and field.remote_field.model:
dependencies.extend(
self._get_dependencies_for_foreign_key(
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py
index 547e0b32c5..33411c9e3e 100644
--- a/tests/migrations/test_autodetector.py
+++ b/tests/migrations/test_autodetector.py
@@ -868,6 +868,18 @@ class AutodetectorTests(TestCase):
"unique_together": {("title", "newfield2")},
},
)
+ book_unique_together = ModelState(
+ "otherapp",
+ "Book",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
+ ("title", models.CharField(max_length=200)),
+ ],
+ {
+ "unique_together": {("author", "title")},
+ },
+ )
attribution = ModelState(
"otherapp",
"Attribution",
@@ -3798,16 +3810,16 @@ class AutodetectorTests(TestCase):
# Right number/type of migrations?
self.assertNumberMigrations(changes, "testapp", 1)
self.assertOperationTypes(
- changes, "testapp", 0, ["RemoveField", "AddField", "DeleteModel"]
+ changes, "testapp", 0, ["RemoveField", "DeleteModel", "AddField"]
)
self.assertOperationAttributes(
changes, "testapp", 0, 0, name="publishers", model_name="author"
)
+ self.assertOperationAttributes(changes, "testapp", 0, 1, name="Publisher")
self.assertOperationAttributes(
- changes, "testapp", 0, 1, name="publishers", model_name="author"
+ changes, "testapp", 0, 2, name="publishers", model_name="author"
)
- self.assertOperationAttributes(changes, "testapp", 0, 2, name="Publisher")
- self.assertOperationFieldAttributes(changes, "testapp", 0, 1, max_length=100)
+ self.assertOperationFieldAttributes(changes, "testapp", 0, 2, max_length=100)
def test_non_circular_foreignkey_dependency_removal(self):
"""
@@ -4346,6 +4358,36 @@ class AutodetectorTests(TestCase):
changes, "testapp", 0, [("otherapp", "__first__")]
)
+ def test_alter_unique_together_fk_to_m2m(self):
+ changes = self.get_changes(
+ [self.author_name, self.book_unique_together],
+ [
+ self.author_name,
+ ModelState(
+ "otherapp",
+ "Book",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ ("author", models.ManyToManyField("testapp.Author")),
+ ("title", models.CharField(max_length=200)),
+ ],
+ ),
+ ],
+ )
+ self.assertNumberMigrations(changes, "otherapp", 1)
+ self.assertOperationTypes(
+ changes, "otherapp", 0, ["AlterUniqueTogether", "RemoveField", "AddField"]
+ )
+ self.assertOperationAttributes(
+ changes, "otherapp", 0, 0, name="book", unique_together=set()
+ )
+ self.assertOperationAttributes(
+ changes, "otherapp", 0, 1, model_name="book", name="author"
+ )
+ self.assertOperationAttributes(
+ changes, "otherapp", 0, 2, model_name="book", name="author"
+ )
+
def test_alter_field_to_fk_dependency_other_app(self):
changes = self.get_changes(
[self.author_empty, self.book_with_no_author_fk],