Commit 28db4af8 authored by Tim Graham's avatar Tim Graham
Browse files

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

Thanks Simon and Markus for reviews.
parent 3f9ec12d
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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`).
+26 −0
Original line number Diff line number Diff line
@@ -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.