From 7b54ddd5e64c96c641b70bb5f0e958a9e2035fb2 Mon Sep 17 00:00:00 2001 From: Clifford Gama Date: Fri, 14 Nov 2025 09:18:59 +0200 Subject: Refs #36025 -- Made get_prep_lookup() pass output_field when wrapping direct values in Value. Previously, only strings were supplied with an output_field when wrapping direct value iterable elements in Value expressions for ExpressionList. This caused problems for __in lookups on JSONField when using expressions alongside direct values, as JSONField values can have different types which need to be adapted by the field's get_db_prep_value(). Refs #36689. Thanks Jacob Walls for the review. --- tests/model_fields/test_jsonfield.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py index 7ab5d17086..d0561e14d2 100644 --- a/tests/model_fields/test_jsonfield.py +++ b/tests/model_fields/test_jsonfield.py @@ -1036,6 +1036,7 @@ class TestQuerying(TestCase): [self.objs[7]], ), ("value__foo__in", [F("value__bax__foo")], [self.objs[7]]), + ("value__foo__in", [F("value__bax__foo"), {}], [self.objs[7]]), ( "value__foo__in", [KeyTransform("foo", KeyTransform("bax", "value")), "baz"], @@ -1045,6 +1046,16 @@ class TestQuerying(TestCase): ("value__foo__in", ["bar", "baz"], [self.objs[7]]), ("value__bar__in", [["foo", "bar"]], [self.objs[7]]), ("value__bar__in", [Value(["foo", "bar"], JSONField())], [self.objs[7]]), + ( + "value__bar__in", + [["foo", "bar"], Value({}, JSONField())], + [self.objs[7]], + ), + ( + "value__bar__in", + [Value(["foo", "bar"], JSONField()), {"a": "b"}], + [self.objs[7]], + ), ("value__bar__in", [["foo", "bar"], ["a"]], [self.objs[7]]), ("value__bax__in", [{"foo": "bar"}, {"a": "b"}], [self.objs[7]]), ("value__h__in", [True, "foo"], [self.objs[4]]), @@ -1313,9 +1324,18 @@ class JSONNullTests(TestCase): def test_filter_in(self): obj = NullableJSONModel.objects.create(value=JSONNull()) + obj2 = NullableJSONModel.objects.create(value=[1]) self.assertSequenceEqual( - NullableJSONModel.objects.filter(value__in=[JSONNull()]), - [obj], + NullableJSONModel.objects.filter(value__in=[JSONNull(), [1], "foo"]), + [obj, obj2], + ) + + def test_key_in(self): + obj1 = NullableJSONModel.objects.create(value={"key": None}) + obj2 = NullableJSONModel.objects.create(value={"key": [1]}) + self.assertSequenceEqual( + NullableJSONModel.objects.filter(value__key__in=[JSONNull(), [1], 0]), + [obj1, obj2], ) def test_bulk_update(self): -- cgit v1.3