Fixed #31831 -- Fixed migration operations ordering when adding order_with_respect_to and constraints/indexes.

This commit is contained in:
Iuri de Silvio 2020-08-01 07:07:18 -03:00 committed by Mariusz Felisiak
parent 366a93f174
commit 58a336a674
2 changed files with 94 additions and 14 deletions

View File

@ -182,12 +182,12 @@ class MigrationAutodetector:
self.generate_removed_fields()
self.generate_added_fields()
self.generate_altered_fields()
self.generate_altered_order_with_respect_to()
self.generate_altered_unique_together()
self.generate_altered_index_together()
self.generate_added_indexes()
self.generate_added_constraints()
self.generate_altered_db_table()
self.generate_altered_order_with_respect_to()
self._sort_migrations()
self._build_migration_list(graph)
@ -613,6 +613,18 @@ class MigrationAutodetector:
dependencies=list(set(dependencies)),
)
# Generate other opns
if order_with_respect_to:
self.add_operation(
app_label,
operations.AlterOrderWithRespectTo(
name=model_name,
order_with_respect_to=order_with_respect_to,
),
dependencies=[
(app_label, model_name, order_with_respect_to, True),
(app_label, model_name, None, True),
]
)
related_dependencies = [
(app_label, model_name, name, True)
for name in sorted(related_fields)
@ -654,19 +666,6 @@ class MigrationAutodetector:
),
dependencies=related_dependencies
)
if order_with_respect_to:
self.add_operation(
app_label,
operations.AlterOrderWithRespectTo(
name=model_name,
order_with_respect_to=order_with_respect_to,
),
dependencies=[
(app_label, model_name, order_with_respect_to, True),
(app_label, model_name, None, True),
]
)
# Fix relationships if the model changed from a proxy model to a
# concrete model.
if (app_label, model_name) in self.old_proxy_keys:

View File

@ -2179,6 +2179,87 @@ class AutodetectorTests(TestCase):
},
)
def test_add_model_order_with_respect_to_index_constraint(self):
tests = [
(
'AddIndex',
{'indexes': [
models.Index(fields=['_order'], name='book_order_idx'),
]},
),
(
'AddConstraint',
{'constraints': [
models.CheckConstraint(
check=models.Q(_order__gt=1),
name='book_order_gt_1',
),
]},
),
]
for operation, extra_option in tests:
with self.subTest(operation=operation):
after = ModelState('testapp', 'Author', [
('id', models.AutoField(primary_key=True)),
('name', models.CharField(max_length=200)),
('book', models.ForeignKey('otherapp.Book', models.CASCADE)),
], options={
'order_with_respect_to': 'book',
**extra_option,
})
changes = self.get_changes([], [self.book, after])
self.assertNumberMigrations(changes, 'testapp', 1)
self.assertOperationTypes(changes, 'testapp', 0, [
'CreateModel', operation,
])
self.assertOperationAttributes(
changes,
'testapp',
0,
0,
name='Author',
options={'order_with_respect_to': 'book'},
)
def test_set_alter_order_with_respect_to_index_constraint_foo_together(self):
tests = [
(
'AddIndex',
{'indexes': [
models.Index(fields=['_order'], name='book_order_idx'),
]},
),
(
'AddConstraint',
{'constraints': [
models.CheckConstraint(
check=models.Q(_order__gt=1),
name='book_order_gt_1',
),
]},
),
('AlterIndexTogether', {'index_together': {('name', '_order')}}),
('AlterUniqueTogether', {'unique_together': {('id', '_order')}}),
]
for operation, extra_option in tests:
with self.subTest(operation=operation):
after = ModelState('testapp', 'Author', [
('id', models.AutoField(primary_key=True)),
('name', models.CharField(max_length=200)),
('book', models.ForeignKey('otherapp.Book', models.CASCADE)),
], options={
'order_with_respect_to': 'book',
**extra_option,
})
changes = self.get_changes(
[self.book, self.author_with_book],
[self.book, after],
)
self.assertNumberMigrations(changes, 'testapp', 1)
self.assertOperationTypes(changes, 'testapp', 0, [
'AlterOrderWithRespectTo', operation,
])
def test_alter_model_managers(self):
"""
Changing the model managers adds a new operation.