Commit ae87ad00 authored by Matthew Wilkes's avatar Matthew Wilkes Committed by Tim Graham
Browse files

Refs #24354 -- Prevented repointing of relations on superclasses when...

Refs #24354 -- Prevented repointing of relations on superclasses when migrating a subclass's name change

Forwardport of test and release note from stable/1.7.x
parent 21ffbb06
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -9,4 +9,6 @@ Django 1.7.7 fixes several bugs in 1.7.6.
Bugfixes
========

* ...
* Fixed renaming of classes in migrations where renaming a subclass would
  cause incorrect state to be recorded for objects that referenced the
  superclass (:ticket:`24354`).
+35 −0
Original line number Diff line number Diff line
@@ -538,6 +538,41 @@ class OperationTests(OperationTestBase):
            self.assertFKExists("test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_rider", "id"))
            self.assertFKNotExists("test_rmwsrf_rider", ["friend_id"], ("test_rmwsrf_horserider", "id"))

    def test_rename_model_with_superclass_fk(self):
        """
        Tests the RenameModel operation on a model which has a superclass that
        has a foreign key.
        """
        project_state = self.set_up_test_model("test_rmwsc", related_model=True, mti_model=True)
        # Test the state alteration
        operation = migrations.RenameModel("ShetlandPony", "LittleHorse")
        self.assertEqual(operation.describe(), "Rename model ShetlandPony to LittleHorse")
        new_state = project_state.clone()
        operation.state_forwards("test_rmwsc", new_state)
        self.assertNotIn(("test_rmwsc", "shetlandpony"), new_state.models)
        self.assertIn(("test_rmwsc", "littlehorse"), new_state.models)
        # RenameModel shouldn't repoint the superclass's relations, only local ones
        self.assertEqual(
            project_state.models["test_rmwsc", "rider"].fields[1][1].rel.to,
            new_state.models["test_rmwsc", "rider"].fields[1][1].rel.to
        )
        # Before running the migration we have a table for Shetland Pony, not Little Horse
        self.assertTableExists("test_rmwsc_shetlandpony")
        self.assertTableNotExists("test_rmwsc_littlehorse")
        if connection.features.supports_foreign_keys:
            # and the foreign key on rider points to pony, not shetland pony
            self.assertFKExists("test_rmwsc_rider", ["pony_id"], ("test_rmwsc_pony", "id"))
            self.assertFKNotExists("test_rmwsc_rider", ["pony_id"], ("test_rmwsc_shetlandpony", "id"))
        with connection.schema_editor() as editor:
            operation.database_forwards("test_rmwsc", editor, project_state, new_state)
        # Now we have a little horse table, not shetland pony
        self.assertTableNotExists("test_rmwsc_shetlandpony")
        self.assertTableExists("test_rmwsc_littlehorse")
        if connection.features.supports_foreign_keys:
            # but the Foreign keys still point at pony, not little horse
            self.assertFKExists("test_rmwsc_rider", ["pony_id"], ("test_rmwsc_pony", "id"))
            self.assertFKNotExists("test_rmwsc_rider", ["pony_id"], ("test_rmwsc_littlehorse", "id"))

    def test_rename_model_with_self_referential_m2m(self):
        app_label = "test_rename_model_with_self_referential_m2m"