summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/expressions.py11
-rw-r--r--docs/releases/5.2.4.txt4
-rw-r--r--tests/expressions/tests.py17
3 files changed, 32 insertions, 0 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 49a29392da..b214be7fa5 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1588,6 +1588,17 @@ class When(Expression):
def set_source_expressions(self, exprs):
self.condition, self.result = exprs
+ def resolve_expression(
+ self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False
+ ):
+ c = super().resolve_expression(query, allow_joins, reuse, summarize, for_save)
+ if for_save and c.condition is not None:
+ # Resolve condition with for_save=False, since it's used as a filter.
+ c.condition = self.condition.resolve_expression(
+ query, allow_joins, reuse, summarize, for_save=False
+ )
+ return c
+
def get_source_fields(self):
# We're only interested in the fields of the result expressions.
return [self.result._output_field_or_none]
diff --git a/docs/releases/5.2.4.txt b/docs/releases/5.2.4.txt
index ebfa556f23..521ed94d6c 100644
--- a/docs/releases/5.2.4.txt
+++ b/docs/releases/5.2.4.txt
@@ -12,3 +12,7 @@ Bugfixes
* Fixed a regression in Django 5.2.2 where :meth:`HttpRequest.get_preferred_type()
<django.http.HttpRequest.get_preferred_type>` incorrectly preferred more
specific media types with a lower quality (:ticket:`36447`).
+
+* Fixed a regression in Django 5.2.3 where ``Value(None, JSONField())`` used in
+ a :class:`~django.db.models.expressions.When` condition was incorrectly
+ serialized as SQL ``NULL`` instead of JSON ``null`` (:ticket:`36453`).
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 89601de85b..a06fbc6b95 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -29,6 +29,7 @@ from django.db.models import (
FloatField,
Func,
IntegerField,
+ JSONField,
Max,
Min,
Model,
@@ -81,6 +82,7 @@ from .models import (
Company,
Employee,
Experiment,
+ JSONFieldModel,
Manager,
Number,
RemoteEmployee,
@@ -365,6 +367,21 @@ class BasicExpressionsTests(TestCase):
Number.objects.all(), [None, None], lambda n: n.float, ordered=False
)
+ @skipUnlessDBFeature("supports_json_field")
+ def test_update_jsonfield_case_when_key_is_null(self):
+ obj = JSONFieldModel.objects.create(data={"key": None})
+ updated = JSONFieldModel.objects.update(
+ data=Case(
+ When(
+ data__key=Value(None, JSONField()),
+ then=Value({"key": "something"}, JSONField()),
+ ),
+ )
+ )
+ self.assertEqual(updated, 1)
+ obj.refresh_from_db()
+ self.assertEqual(obj.data, {"key": "something"})
+
def test_filter_with_join(self):
# F Expressions can also span joins
Company.objects.update(point_of_contact=F("ceo"))