浏览代码

Fixed #34820 -- Fixed migrations crash when changing a ForeignObject field.

donghao 1 年之前
父节点
当前提交
71820c9f91
共有 3 个文件被更改,包括 49 次插入0 次删除
  1. 1 0
      AUTHORS
  2. 2 0
      django/db/backends/base/schema.py
  3. 46 0
      tests/migrations/test_operations.py

+ 1 - 0
AUTHORS

@@ -391,6 +391,7 @@ answer newbie questions, and generally made Django that much better:
     Hang Park <hangpark@kaist.ac.kr>
     Hannes Ljungberg <hannes.ljungberg@gmail.com>
     Hannes Struß <x@hannesstruss.de>
+    Hao Dong <https://github.com/RelaxedDong>
     Harm Geerts <hgeerts@gmail.com>
     Hasan Ramezani <hasan.r67@gmail.com>
     Hawkeye

+ 2 - 0
django/db/backends/base/schema.py

@@ -1617,6 +1617,8 @@ class BaseDatabaseSchemaEditor:
         return output
 
     def _field_should_be_altered(self, old_field, new_field, ignore=None):
+        if not old_field.concrete and not new_field.concrete:
+            return False
         ignore = ignore or set()
         _, old_path, old_args, old_kwargs = old_field.deconstruct()
         _, new_path, new_args, new_kwargs = new_field.deconstruct()

+ 46 - 0
tests/migrations/test_operations.py

@@ -2306,6 +2306,52 @@ class OperationTests(OperationTestBase):
                 operation.database_forwards(app_label, editor, new_state, project_state)
         self.assertColumnExists(rider_table, "pony_id")
 
+    def test_alter_field_foreignobject_noop(self):
+        app_label = "test_alflfo_noop"
+        project_state = self.set_up_test_model(app_label)
+        project_state = self.apply_operations(
+            app_label,
+            project_state,
+            [
+                migrations.CreateModel(
+                    "Rider",
+                    fields=[
+                        ("pony_id", models.IntegerField()),
+                        (
+                            "pony",
+                            models.ForeignObject(
+                                f"{app_label}.Pony",
+                                models.CASCADE,
+                                from_fields=("pony_id",),
+                                to_fields=("id",),
+                            ),
+                        ),
+                    ],
+                ),
+            ],
+        )
+        operation = migrations.AlterField(
+            "Rider",
+            "pony",
+            models.ForeignObject(
+                f"{app_label}.Pony",
+                models.CASCADE,
+                from_fields=("pony_id",),
+                to_fields=("id",),
+                null=True,
+            ),
+        )
+        new_state = project_state.clone()
+        operation.state_forwards(app_label, new_state)
+        with (
+            CaptureQueriesContext(connection) as ctx,
+            connection.schema_editor() as editor,
+        ):
+            operation.database_forwards(app_label, editor, project_state, new_state)
+        self.assertIs(
+            any("ALTER" in query["sql"] for query in ctx.captured_queries), False
+        )
+
     @skipUnlessDBFeature("supports_comments")
     def test_alter_model_table_comment(self):
         app_label = "test_almotaco"