Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Autodetect field renames. HAHAHA. AHAHAHAHA. YES.

  • Loading branch information...
commit 92a10f5552315b22e7d374123e3d09249b6b9883 1 parent 0e8ee50
@andrewgodwin andrewgodwin authored
View
21 django/db/migrations/autodetector.py
@@ -68,7 +68,26 @@ def changes(self):
old_field_names = set([x for x, y in old_model_state.fields])
new_field_names = set([x for x, y in new_model_state.fields])
for field_name in new_field_names - old_field_names:
- field = [y for x, y in new_model_state.fields if x == field_name][0]
+ field = new_model_state.get_field_by_name(field_name)
+ # Scan to see if this is actually a rename!
+ field_dec = field.deconstruct()[1:]
+ found_rename = False
+ for removed_field_name in (old_field_names - new_field_names):
+ if old_model_state.get_field_by_name(removed_field_name).deconstruct()[1:] == field_dec:
+ self.add_to_migration(
+ app_label,
+ operations.RenameField(
+ model_name = model_name,
+ old_name = removed_field_name,
+ new_name = field_name,
+ )
+ )
+ old_field_names.remove(removed_field_name)
+ new_field_names.remove(field_name)
+ found_rename = True
+ break
+ if found_rename:
+ continue
# You can't just add NOT NULL fields with no default
if not field.null and not field.has_default():
field.default = self.questioner.ask_not_null_addition(field_name, model_name)
View
21 tests/migrations/test_autodetector.py
@@ -14,6 +14,7 @@ class AutodetectorTests(TestCase):
author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))])
author_name = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200))])
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))])
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))])
@@ -22,7 +23,7 @@ def make_project_state(self, model_states):
"Shortcut to make ProjectStates from lists of predefined models"
project_state = ProjectState()
for model_state in model_states:
- project_state.add_model_state(model_state)
+ project_state.add_model_state(model_state.clone())
return project_state
def test_arrange_for_graph(self):
@@ -148,3 +149,21 @@ def test_alter_field(self):
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "AlterField")
self.assertEqual(action.name, "name")
+
+ def test_rename_field(self):
+ "Tests autodetection of renamed fields"
+ # Make state
+ before = self.make_project_state([self.author_name])
+ after = self.make_project_state([self.author_name_renamed])
+ autodetector = MigrationAutodetector(before, after)
+ changes = autodetector.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__, "RenameField")
+ self.assertEqual(action.old_name, "name")
+ self.assertEqual(action.new_name, "names")
Please sign in to comment.
Something went wrong with that request. Please try again.