[4.1.x] Fixed #31788 -- Fixed migration optimization after altering field to ManyToManyField.
This makes AddField() used for altering to ManyToManyField, dependent
on the prior RemoveField.
Backport of 798b6c23ee
from main
This commit is contained in:
parent
0fb0355271
commit
9fce76a237
|
@ -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(
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue