diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 89e2dceeaf..ccdf62bcfe 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -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: diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 0c30cd0489..339f742057 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -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.