Fixed #31788 -- Fixed migration optimization after altering field to ManyToManyField.
This makes AddField() used for altering to ManyToManyField, dependent on the prior RemoveField.
This commit is contained in:
parent
6f73eb9d90
commit
798b6c23ee
|
@ -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