1
0
mirror of https://github.com/django/django.git synced 2025-08-21 17:29:13 +00:00

Refs #36438 -- Made FieldOperation.references_field() detect references in GeneratedField.expression.

Thanks to Simon Charette for the suggestion and review.
This commit is contained in:
Clifford Gama 2025-07-06 08:32:09 +02:00 committed by Sarah Boyce
parent 1a7fc0f65d
commit 45ba7683a6
2 changed files with 29 additions and 7 deletions

View File

@ -1,5 +1,5 @@
from django.db.migrations.utils import field_references from django.db.migrations.utils import field_references
from django.db.models import NOT_PROVIDED from django.db.models import NOT_PROVIDED, Model
from django.utils.copy import replace from django.utils.copy import replace
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -49,12 +49,19 @@ class FieldOperation(Operation):
if model_name_lower == self.model_name_lower: if model_name_lower == self.model_name_lower:
if name == self.name: if name == self.name:
return True return True
elif ( if self.field:
self.field if (
and hasattr(self.field, "from_fields") hasattr(self.field, "from_fields")
and name in self.field.from_fields and name in self.field.from_fields
): ):
return True return True
elif self.field.generated and any(
field_name == name
for field_name, *_ in Model._get_expr_references(
self.field.expression
)
):
return True
# Check if this operation remotely references the field. # Check if this operation remotely references the field.
if self.field is None: if self.field is None:
return False return False

View File

@ -6842,6 +6842,21 @@ class FieldOperationTests(SimpleTestCase):
operation.references_field("Through", "second", "migrations"), True operation.references_field("Through", "second", "migrations"), True
) )
def test_references_field_by_generated_field(self):
operation = FieldOperation(
"Model",
"field",
models.GeneratedField(
expression=F("foo") + F("bar"),
output_field=models.IntegerField(),
db_persist=True,
),
)
self.assertIs(operation.references_field("Model", "foo", "migrations"), True)
self.assertIs(operation.references_field("Model", "bar", "migrations"), True)
self.assertIs(operation.references_field("Model", "alien", "migrations"), False)
self.assertIs(operation.references_field("Other", "foo", "migrations"), False)
class BaseOperationTests(SimpleTestCase): class BaseOperationTests(SimpleTestCase):
def test_formatted_description_no_category(self): def test_formatted_description_no_category(self):