Loading django/db/migrations/operations/models.py +21 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,27 @@ class RenameModel(Operation): related_object.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): self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower Loading docs/releases/1.7.4.txt +3 −0 Original line number Diff line number Diff line Loading @@ -11,3 +11,6 @@ Bugfixes * Fixed a migration crash when unapplying ``contrib.contenttypes``’s or ``contrib.auth``’s first migration (:ticket:`24075`). * Made the migration's ``RenameModel`` operation rename ``ManyToManyField`` tables (:ticket:`24135`). tests/migrations/test_operations.py +26 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,32 @@ class OperationTests(OperationTestBase): pony = Pony.objects.create() 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): """ Tests the AddField operation. Loading Loading
django/db/migrations/operations/models.py +21 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,27 @@ class RenameModel(Operation): related_object.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): self.new_name_lower, self.old_name_lower = self.old_name_lower, self.new_name_lower Loading
docs/releases/1.7.4.txt +3 −0 Original line number Diff line number Diff line Loading @@ -11,3 +11,6 @@ Bugfixes * Fixed a migration crash when unapplying ``contrib.contenttypes``’s or ``contrib.auth``’s first migration (:ticket:`24075`). * Made the migration's ``RenameModel`` operation rename ``ManyToManyField`` tables (:ticket:`24135`).
tests/migrations/test_operations.py +26 −0 Original line number Diff line number Diff line Loading @@ -553,6 +553,32 @@ class OperationTests(OperationTestBase): pony = Pony.objects.create() 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): """ Tests the AddField operation. Loading