Commit 6ae1e3ba authored by Carl Meyer's avatar Carl Meyer
Browse files

Merge pull request #3563 from MarkusH/ticket23859

Fixed #23859 -- Fixed a migration crash when a field is renamed that is part of an index_together
parents 19ae13d9 7b4a9945
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -177,12 +177,13 @@ class RenameField(Operation):
            (self.new_name if n == self.old_name else n, f)
            for n, f in state.models[app_label, self.model_name.lower()].fields
        ]
        # Fix unique_together to refer to the new field
        # Fix index/unique_together to refer to the new field
        options = state.models[app_label, self.model_name.lower()].options
        if "unique_together" in options:
            options['unique_together'] = [
                [self.new_name if n == self.old_name else n for n in unique]
                for unique in options['unique_together']
        for option in ('index_together', 'unique_together'):
            if option in options:
                options[option] = [
                    [self.new_name if n == self.old_name else n for n in together]
                    for together in options[option]
                ]

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
+3 −0
Original line number Diff line number Diff line
@@ -59,3 +59,6 @@ Bugfixes

* Fixed a custom field type validation error with MySQL backend when
  ``db_type`` returned ``None`` (:ticket:`23761`).

* Fixed a migration crash when a field is renamed that is part of an
  ``index_together`` (:ticket:`23859`).
+6 −2
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ class OperationTestBase(MigrationTestBase):

    def set_up_test_model(self, app_label, second_model=False, third_model=False,
            related_model=False, mti_model=False, proxy_model=False,
            unique_together=False, options=False, db_table=None):
            unique_together=False, options=False, db_table=None, index_together=False):
        """
        Creates a test model state and database table.
        """
@@ -81,6 +81,7 @@ class OperationTestBase(MigrationTestBase):
        # Make the "current" state
        model_options = {
            "swappable": "TEST_SWAP_MODEL",
            "index_together": [["pink", "weight"]] if index_together else [],
            "unique_together": [["pink", "weight"]] if unique_together else [],
        }
        if options:
@@ -984,7 +985,7 @@ class OperationTests(OperationTestBase):
        """
        Tests the RenameField operation.
        """
        project_state = self.set_up_test_model("test_rnfl", unique_together=True)
        project_state = self.set_up_test_model("test_rnfl", unique_together=True, index_together=True)
        # Test the state alteration
        operation = migrations.RenameField("Pony", "pink", "blue")
        self.assertEqual(operation.describe(), "Rename field pink on Pony to blue")
@@ -995,6 +996,9 @@ class OperationTests(OperationTestBase):
        # Make sure the unique_together has the renamed column too
        self.assertIn("blue", new_state.models["test_rnfl", "pony"].options['unique_together'][0])
        self.assertNotIn("pink", new_state.models["test_rnfl", "pony"].options['unique_together'][0])
        # Make sure the index_together has the renamed column too
        self.assertIn("blue", new_state.models["test_rnfl", "pony"].options['index_together'][0])
        self.assertNotIn("pink", new_state.models["test_rnfl", "pony"].options['index_together'][0])
        # Test the database alteration
        self.assertColumnExists("test_rnfl_pony", "pink")
        self.assertColumnNotExists("test_rnfl_pony", "blue")