Fixed #24135 -- Made RenameModel rename many-to-many tables.

Thanks Simon and Markus for reviews.
This commit is contained in:
Tim Graham 2015-01-15 09:56:07 -05:00
parent 3f9ec12d9c
commit 28db4af80a
3 changed files with 50 additions and 0 deletions

View File

@ -216,6 +216,27 @@ class RenameModel(Operation):
related_object.field, related_object.field,
to_field, to_field,
) )
# Rename M2M fields whose name is based on this model's name.
fields = zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many)
for (old_field, new_field) in fields:
# Skip self-referential fields as these are renamed above.
if new_field.model == new_field.related_model or not new_field.rel.through._meta.auto_created:
continue
# Rename the M2M table that's based on this model's name.
old_m2m_model = old_field.rel.through
new_m2m_model = new_field.rel.through
schema_editor.alter_db_table(
new_m2m_model,
old_m2m_model._meta.db_table,
new_m2m_model._meta.db_table,
)
# Rename the column in the M2M table that's based on this
# model's name.
schema_editor.alter_field(
new_m2m_model,
old_m2m_model._meta.get_field(old_model._meta.model_name),
new_m2m_model._meta.get_field(new_model._meta.model_name),
)
def database_backwards(self, app_label, schema_editor, from_state, to_state): def database_backwards(self, app_label, schema_editor, from_state, to_state):
self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower

View File

@ -11,3 +11,6 @@ Bugfixes
* Fixed a migration crash when unapplying ``contrib.contenttypes``s or * Fixed a migration crash when unapplying ``contrib.contenttypes``s or
``contrib.auth``s first migration (:ticket:`24075`). ``contrib.auth``s first migration (:ticket:`24075`).
* Made the migration's ``RenameModel`` operation rename ``ManyToManyField``
tables (:ticket:`24135`).

View File

@ -553,6 +553,32 @@ class OperationTests(OperationTestBase):
pony = Pony.objects.create() pony = Pony.objects.create()
pony.ponies.add(pony) pony.ponies.add(pony)
def test_rename_model_with_m2m(self):
app_label = "test_rename_model_with_m2m"
project_state = self.apply_operations(app_label, ProjectState(), operations=[
migrations.CreateModel("Rider", fields=[]),
migrations.CreateModel("Pony", fields=[
("riders", models.ManyToManyField("Rider")),
]),
])
Pony = project_state.apps.get_model(app_label, "Pony")
Rider = project_state.apps.get_model(app_label, "Rider")
pony = Pony.objects.create()
rider = Rider.objects.create()
pony.riders.add(rider)
project_state = self.apply_operations(app_label, project_state, operations=[
migrations.RenameModel("Pony", "Pony2"),
])
Pony = project_state.apps.get_model(app_label, "Pony2")
Rider = project_state.apps.get_model(app_label, "Rider")
pony = Pony.objects.create()
rider = Rider.objects.create()
pony.riders.add(rider)
self.assertEqual(Pony.objects.count(), 2)
self.assertEqual(Rider.objects.count(), 2)
self.assertEqual(Pony._meta.get_field('riders').rel.through.objects.count(), 2)
def test_add_field(self): def test_add_field(self):
""" """
Tests the AddField operation. Tests the AddField operation.