summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2016-08-20 16:34:06 -0400
committerSimon Charette <charette.s@gmail.com>2016-08-24 01:17:18 -0400
commitd1757d8df486b689172d2584ded52fad916bcc33 (patch)
tree980ca1d049ea7743a95a81460181d81015160e50
parentad25fe73506d80ffcaac135ad0a8d09552b70d70 (diff)
Fixed #27044 -- Included already applied migration changes in the post-migrate state when the execution plan is empty.
Refs #24100. Thanks tkhyn for the report and Tim for the review.
-rw-r--r--django/core/management/commands/migrate.py12
-rw-r--r--django/db/migrations/executor.py10
-rw-r--r--docs/releases/1.10.1.txt4
-rw-r--r--tests/migrate_signals/tests.py10
-rw-r--r--tests/migrations/test_executor.py8
5 files changed, 36 insertions, 8 deletions
diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py
index b6c8748bff..4c8e008374 100644
--- a/django/core/management/commands/migrate.py
+++ b/django/core/management/commands/migrate.py
@@ -175,7 +175,6 @@ class Command(BaseCommand):
if self.verbosity >= 1:
self.stdout.write(self.style.MIGRATE_HEADING("Running migrations:"))
if not plan:
- executor.check_replacements()
if self.verbosity >= 1:
self.stdout.write(" No migrations to apply.")
# If there's changes that aren't in migrations yet, tell them how to fix it.
@@ -194,14 +193,15 @@ class Command(BaseCommand):
"migrations, and then re-run 'manage.py migrate' to "
"apply them."
))
- post_migrate_apps = pre_migrate_apps
+ fake = False
+ fake_initial = False
else:
fake = options['fake']
fake_initial = options['fake_initial']
- post_migrate_project_state = executor.migrate(
- targets, plan, fake=fake, fake_initial=fake_initial
- )
- post_migrate_apps = post_migrate_project_state.apps
+ post_migrate_project_state = executor.migrate(
+ targets, plan, fake=fake, fake_initial=fake_initial
+ )
+ post_migrate_apps = post_migrate_project_state.apps
# Re-render models of real apps to include relationships now that
# we've got a final state. This wouldn't be necessary if real apps
diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py
index fb9c7a93a4..11a96ec81b 100644
--- a/django/db/migrations/executor.py
+++ b/django/db/migrations/executor.py
@@ -82,9 +82,15 @@ class MigrationExecutor(object):
all_backwards = all(backwards for mig, backwards in plan)
if not plan:
- # Nothing to do for an empty plan, except for building the post
- # migrate project state
+ # The resulting state should include applied migrations.
state = self._create_project_state()
+ applied_migrations = {
+ self.loader.graph.nodes[key] for key in self.loader.applied_migrations
+ if key in self.loader.graph.nodes
+ }
+ for migration, _ in full_plan:
+ if migration in applied_migrations:
+ migration.mutate_state(state, preserve=False)
elif all_forwards == all_backwards:
# This should only happen if there's a mixed plan
raise InvalidMigrationPlan(
diff --git a/docs/releases/1.10.1.txt b/docs/releases/1.10.1.txt
index 3e73483e37..46188aa2da 100644
--- a/docs/releases/1.10.1.txt
+++ b/docs/releases/1.10.1.txt
@@ -68,3 +68,7 @@ Bugfixes
* Added the database alias to the ``InconsistentMigrationHistory`` message
raised by ``makemigrations`` and ``migrate`` (:ticket:`27089`).
+
+* Fixed the creation of ``ContentType`` and ``Permission`` objects for models
+ of applications without migrations when calling the ``migrate`` command with
+ no migrations to apply (:ticket:`27044`).
diff --git a/tests/migrate_signals/tests.py b/tests/migrate_signals/tests.py
index d422ab84b4..bb3ea0ccc9 100644
--- a/tests/migrate_signals/tests.py
+++ b/tests/migrate_signals/tests.py
@@ -113,3 +113,13 @@ class MigrateSignalTests(TransactionTestCase):
[model._meta.label for model in post_migrate_receiver.call_args['apps'].get_models()],
['migrate_signals.Signal']
)
+ # Migrating with an empty plan.
+ post_migrate_receiver = Receiver(signals.post_migrate)
+ management.call_command(
+ 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY,
+ interactive=MIGRATE_INTERACTIVE, stdout=stdout,
+ )
+ self.assertEqual(
+ [model._meta.label for model in post_migrate_receiver.call_args['apps'].get_models()],
+ ['migrate_signals.Signal']
+ )
diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py
index b61f51f457..847b11c088 100644
--- a/tests/migrations/test_executor.py
+++ b/tests/migrations/test_executor.py
@@ -168,6 +168,14 @@ class ExecutorTests(MigrationTestBase):
("migrations2", "0001_initial"),
])
self.assertEqual(plan, [])
+ # The resulting state should include applied migrations.
+ state = executor.migrate([
+ ("migrations", "0002_second"),
+ ("migrations2", "0001_initial"),
+ ])
+ self.assertIn(('migrations', 'book'), state.models)
+ self.assertIn(('migrations', 'author'), state.models)
+ self.assertIn(('migrations2', 'otherauthor'), state.models)
# Erase all the fake records
executor.recorder.record_unapplied("migrations2", "0001_initial")
executor.recorder.record_unapplied("migrations", "0002_second")