[Django] #36440: JSON null saved instead of NULL

2 views
Skip to first unread message

Django

unread,
Jun 5, 2025, 8:40:40 AM6/5/25
to django-...@googlegroups.com
#36440: JSON null saved instead of NULL
-------------------------------------+-------------------------------------
Reporter: Adam | Owner: Adam Johnson
Johnson |
Type: Bug | Status: assigned
Component: Database | Version: 5.2
layer (models, ORM) |
Severity: Release | Keywords:
blocker |
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I have a client project with a Django model that has a `JSONField` and a
check constraint requiring the field to either contain SQL `NULL` or a
JSON object (via a custom database function calling PostgreSQL's
`jsonb_typeof`). Upgrading to Django 5.2 causes a `bulk_update()` query on
that model to start failing with `IntegrityError`, because the JSON `null`
is serialized instead (`'null'::json` in PostgreSQL syntax).

Like #36404 and #36405, this is another bug that bisects to
e306687a3a5507d59365ba9bf545010e5fd4b2a8.

The issue:

1. `BaseExpression.resolve_expression()` no longer passes the `for_save`
parameter through to source expressions.
2. When a source expression is a `Value`, `for_save` being `False`
prevents it from calling `Field.get_db_prep_save()`:
https://github.com/django/django/blob/f0a87895ffaf6532a22143b5e2e304c59b7958ae/django/db/models/expressions.py#L1170-L1173
.
3. `JSONField.get_db_prep_save()` has specific behaviour for `None`,
ensuring it's returned as-is rather than wrapped as JSON:
https://github.com/django/django/blob/main/django/db/models/fields/json.py#L110-L111
4. The missed call means `None` is wrapped as JSON null, which fails the
model's check constraint.

Patch incoming.
--
Ticket URL: <https://code.djangoproject.com/ticket/36440>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Reply all
Reply to author
Forward
0 new messages