Commit bf4dc573 authored by Markus Holtermann's avatar Markus Holtermann
Browse files

[1.8.x] Fixed #24725 -- Allowed renaming of target models in ManyToMany relations

This is a regression caused by introducing rendered migration states in
1aa3e09c and the _meta refactoring in fb48eb05.

Thanks to Danilo Bargen for reporting the issue and Marten Kenbeek and
Tim Graham for triaging the bug and providing the initial test case.

Backport of 63f9b633 from master
parent 49dea416
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ class RenameModel(Operation):
        # Get all of the related objects we need to repoint
        all_related_objects = (
            f for f in model._meta.get_fields(include_hidden=True)
            if f.auto_created and not f.concrete and not (f.hidden or f.many_to_many)
            if f.auto_created and not f.concrete and (not f.hidden or f.many_to_many)
        )
        # Rename the model
        state.models[app_label, self.new_name_lower] = state.models[app_label, self.old_name_lower]
+3 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ Bugfixes
* Restored the ability to use iterators as queryset filter arguments
  (:ticket:`24719`).

* Fixed a migration crash when renaming the target model of a many-to-many
  relation (:ticket:`24725`).

Optimizations
=============

+26 −0
Original line number Diff line number Diff line
@@ -614,6 +614,32 @@ class OperationTests(OperationTestBase):
        self.assertEqual(Rider.objects.count(), 2)
        self.assertEqual(Pony._meta.get_field('riders').rel.through.objects.count(), 2)

    def test_rename_m2m_target_model(self):
        app_label = "test_rename_m2m_target_model"
        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("Rider", "Rider2"),
        ])
        Pony = project_state.apps.get_model(app_label, "Pony")
        Rider = project_state.apps.get_model(app_label, "Rider2")
        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.