diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py index 04d2b778f5..ecd9d0fdf2 100644 --- a/django/db/migrations/executor.py +++ b/django/db/migrations/executor.py @@ -132,11 +132,13 @@ class MigrationExecutor(object): """ project_state = self.loader.project_state((migration.app_label, migration.name), at_end=True) apps = project_state.render() + found_create_migration = False for operation in migration.operations: if isinstance(operation, migrations.CreateModel): model = apps.get_model(migration.app_label, operation.name) if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()): return False - else: - return False - return True + found_create_migration = True + # If we get this far and we found at least one CreateModel migration, + # the migration is considered implicitly applied. + return found_create_migration diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py index b6909a15a1..e933f9d8bd 100644 --- a/tests/migrations/test_executor.py +++ b/tests/migrations/test_executor.py @@ -155,6 +155,12 @@ class ExecutorTests(MigrationTestBase): self.assertTableNotExists("migrations_author") self.assertTableNotExists("migrations_tribble") # Run it normally + self.assertEqual( + executor.migration_plan([("migrations", "0001_initial")]), + [ + (executor.loader.graph.nodes["migrations", "0001_initial"], False), + ], + ) executor.migrate([("migrations", "0001_initial")]) # Are the tables there now? self.assertTableExists("migrations_author") @@ -171,9 +177,17 @@ class ExecutorTests(MigrationTestBase): # Make sure that was faked self.assertEqual(state["faked"], True) # Finally, migrate forwards; this should fake-apply our initial migration + executor.loader.build_graph() + self.assertEqual( + executor.migration_plan([("migrations", "0001_initial")]), + [ + (executor.loader.graph.nodes["migrations", "0001_initial"], False), + ], + ) executor.migrate([("migrations", "0001_initial")]) self.assertEqual(state["faked"], True) # And migrate back to clean up the database + executor.loader.build_graph() executor.migrate([("migrations", None)]) self.assertTableNotExists("migrations_author") self.assertTableNotExists("migrations_tribble") diff --git a/tests/migrations/test_migrations/0001_initial.py b/tests/migrations/test_migrations/0001_initial.py index 581d536814..9286d0f02b 100644 --- a/tests/migrations/test_migrations/0001_initial.py +++ b/tests/migrations/test_migrations/0001_initial.py @@ -25,6 +25,11 @@ class Migration(migrations.Migration): ("id", models.AutoField(primary_key=True)), ("fluffy", models.BooleanField(default=True)), ], - ) + ), + + migrations.AlterUniqueTogether( + name='author', + unique_together=set([('name', 'slug')]), + ), ]