summaryrefslogtreecommitdiff
path: root/tests/expressions
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-02-18 12:43:38 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2025-03-01 19:57:53 +0100
commitfc303551077c3e023fe4f9d01fc1b3026c816fa4 (patch)
treeb0df1aee2d06932305f46e2aea596986b4f20460 /tests/expressions
parentff3aaf036f0cb66cd8f404cd51c603e68aaa7676 (diff)
Fixed #36198 -- Implemented unresolved transform expression replacement.
This allows the proper resolving of F("field__transform") when performing constraint validation. Thanks Tom Hall for the report and Sarah for the test.
Diffstat (limited to 'tests/expressions')
-rw-r--r--tests/expressions/tests.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 89601de85b..1fb4e2f34d 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -58,10 +58,12 @@ from django.db.models.expressions import (
from django.db.models.functions import (
Coalesce,
Concat,
+ ExtractDay,
Left,
Length,
Lower,
Substr,
+ TruncDate,
Upper,
)
from django.db.models.sql import constants
@@ -1330,6 +1332,38 @@ class FTests(SimpleTestCase):
with self.assertRaisesMessage(TypeError, msg):
"" in F("name")
+ def test_replace_expressions_transform(self):
+ replacements = {F("timestamp"): Value(None)}
+ transform_ref = F("timestamp__date")
+ self.assertIs(transform_ref.replace_expressions(replacements), transform_ref)
+ invalid_transform_ref = F("timestamp__invalid")
+ self.assertIs(
+ invalid_transform_ref.replace_expressions(replacements),
+ invalid_transform_ref,
+ )
+ replacements = {F("timestamp"): Value(datetime.datetime(2025, 3, 1, 14, 10))}
+ self.assertEqual(
+ F("timestamp__date").replace_expressions(replacements),
+ TruncDate(Value(datetime.datetime(2025, 3, 1, 14, 10))),
+ )
+ self.assertEqual(
+ F("timestamp__date__day").replace_expressions(replacements),
+ ExtractDay(TruncDate(Value(datetime.datetime(2025, 3, 1, 14, 10)))),
+ )
+ invalid_nested_transform_ref = F("timestamp__date__invalid")
+ self.assertIs(
+ invalid_nested_transform_ref.replace_expressions(replacements),
+ invalid_nested_transform_ref,
+ )
+ # `replacements` is not unnecessarily looked up a second time for
+ # transform-less field references as it's the case the vast majority of
+ # the time.
+ mock_replacements = mock.Mock()
+ mock_replacements.get.return_value = None
+ field_ref = F("name")
+ self.assertIs(field_ref.replace_expressions(mock_replacements), field_ref)
+ mock_replacements.get.assert_called_once_with(field_ref)
+
class ExpressionsTests(TestCase):
def test_F_reuse(self):