Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Migration autodetector now corerctly deals with proxy models

  • Loading branch information...
commit 05e14e8eaf577e64dc45e26466ebb6117589e572 1 parent a962286
Andrew Godwin andrewgodwin authored
18 django/db/migrations/autodetector.py
View
@@ -50,8 +50,20 @@ def _detect_changes(self):
self.migrations = {}
old_app_cache = self.from_state.render()
new_app_cache = self.to_state.render()
+ # Prepare lists of old/new model keys that we care about
+ # (i.e. ignoring proxy ones)
+ old_model_keys = [
+ (al, mn)
+ for al, mn in self.from_state.models.keys()
+ if not old_app_cache.get_model(al, mn)._meta.proxy
+ ]
+ new_model_keys = [
+ (al, mn)
+ for al, mn in self.to_state.models.keys()
+ if not new_app_cache.get_model(al, mn)._meta.proxy
+ ]
# Adding models. Phase 1 is adding models with no outward relationships.
- added_models = set(self.to_state.models.keys()) - set(self.from_state.models.keys())
+ added_models = set(new_model_keys) - set(old_model_keys)
pending_add = {}
for app_label, model_name in added_models:
model_state = self.to_state.models[app_label, model_name]
@@ -130,7 +142,7 @@ def _detect_changes(self):
)
self.add_dependency(app_label, other_app_label)
# Removing models
- removed_models = set(self.from_state.models.keys()) - set(self.to_state.models.keys())
+ removed_models = set(old_model_keys) - set(new_model_keys)
for app_label, model_name in removed_models:
model_state = self.from_state.models[app_label, model_name]
self.add_to_migration(
@@ -140,7 +152,7 @@ def _detect_changes(self):
)
)
# Changes within models
- kept_models = set(self.from_state.models.keys()).intersection(self.to_state.models.keys())
+ kept_models = set(old_model_keys).intersection(new_model_keys)
for app_label, model_name in kept_models:
old_model_state = self.from_state.models[app_label, model_name]
new_model_state = self.to_state.models[app_label, model_name]
27 tests/migrations/test_autodetector.py
View
@@ -16,6 +16,8 @@ class AutodetectorTests(TestCase):
author_name_longer = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=400))])
author_name_renamed = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("names", models.CharField(max_length=200))])
author_with_book = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("book", models.ForeignKey("otherapp.Book"))])
+ author_proxy = ModelState("testapp", "AuthorProxy", [], {"proxy": True}, ("testapp.author", ))
+ author_proxy_notproxy = ModelState("testapp", "AuthorProxy", [], {}, ("testapp.author", ))
other_pony = ModelState("otherapp", "Pony", [("id", models.AutoField(primary_key=True))])
other_stable = ModelState("otherapp", "Stable", [("id", models.AutoField(primary_key=True))])
third_thing = ModelState("thirdapp", "Thing", [("id", models.AutoField(primary_key=True))])
@@ -272,3 +274,28 @@ def test_unique_together_ordering(self):
self.assertEqual(action.__class__.__name__, "AlterUniqueTogether")
self.assertEqual(action.name, "book")
self.assertEqual(action.unique_together, set([("title", "author")]))
+
+ def test_proxy_ignorance(self):
+ "Tests that the autodetector correctly ignores proxy models"
+ # First, we test adding a proxy model
+ before = self.make_project_state([self.author_empty])
+ after = self.make_project_state([self.author_empty, self.author_proxy])
+ autodetector = MigrationAutodetector(before, after)
+ changes = autodetector._detect_changes()
+ # Right number of migrations?
+ self.assertEqual(len(changes), 0)
+
+ # Now, we test turning a proxy model into a non-proxy model
+ before = self.make_project_state([self.author_empty, self.author_proxy])
+ after = self.make_project_state([self.author_empty, self.author_proxy_notproxy])
+ autodetector = MigrationAutodetector(before, after)
+ changes = autodetector._detect_changes()
+ # Right number of migrations?
+ self.assertEqual(len(changes['testapp']), 1)
+ # Right number of actions?
+ migration = changes['testapp'][0]
+ self.assertEqual(len(migration.operations), 1)
+ # Right action?
+ action = migration.operations[0]
+ self.assertEqual(action.__class__.__name__, "CreateModel")
+ self.assertEqual(action.name, "AuthorProxy")
Please sign in to comment.
Something went wrong with that request. Please try again.