1
0
mirror of https://github.com/django/django.git synced 2025-11-07 07:15:35 +00:00

Fixed #35381 -- Added JSONNull() expression.

Thanks Jacob Walls for the review.
This commit is contained in:
Clifford Gama
2025-08-07 17:26:15 +02:00
committed by Jacob Walls
parent ab108bf94d
commit adc25a9a66
7 changed files with 213 additions and 10 deletions

View File

@@ -1048,13 +1048,15 @@ the following example model::
def __str__(self):
return self.name
.. _storing-and-querying-for-none:
Storing and querying for ``None``
---------------------------------
As with other fields, storing ``None`` as the field's value will store it as
SQL ``NULL``. While not recommended, it is possible to store JSON scalar
``null`` instead of SQL ``NULL`` by using :class:`Value(None, JSONField())
<django.db.models.Value>`.
``null`` instead of SQL ``NULL`` by using the :class:`JSONNull()
<django.db.models.JSONNull>` expression.
Whichever of the values is stored, when retrieved from the database, the Python
representation of the JSON scalar ``null`` is the same as SQL ``NULL``, i.e.
@@ -1064,18 +1066,21 @@ This only applies to ``None`` as the top-level value of the field. If ``None``
is inside a :class:`list` or :class:`dict`, it will always be interpreted
as JSON ``null``.
When querying, ``None`` value will always be interpreted as JSON ``null``. To
query for SQL ``NULL``, use :lookup:`isnull`:
When querying, :lookup:`isnull=True <isnull>` is used to match SQL ``NULL``,
while exact-matching ``JSONNull()`` is used to match JSON ``null``.
.. versionchanged:: 6.1
``JSONNull()`` expression was added.
.. code-block:: pycon
>>> from django.db.models import JSONNull
>>> Dog.objects.create(name="Max", data=None) # SQL NULL.
<Dog: Max>
>>> Dog.objects.create(name="Archie", data=Value(None, JSONField())) # JSON null.
>>> Dog.objects.create(name="Archie", data=JSONNull()) # JSON null.
<Dog: Archie>
>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value(None, JSONField()))
>>> Dog.objects.filter(data=JSONNull())
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data__isnull=True)
<QuerySet [<Dog: Max>]>
@@ -1091,6 +1096,14 @@ Unless you are sure you wish to work with SQL ``NULL`` values, consider setting
Storing JSON scalar ``null`` does not violate :attr:`null=False
<django.db.models.Field.null>`.
.. admonition:: Storing JSON ``null`` inside JSON data
While :class:`JSONNull() <django.db.models.JSONNull>` can be used in
:lookup:`jsonfield.key` exact lookups, it cannot be stored inside
:class:`dict` or :class:`list` instances meant to be saved in a
``JSONField``, unless a custom encoder is used. If you don't want to use
a custom encoder, use ``None`` instead.
.. fieldlookup:: jsonfield.key
.. _key-index-and-path-transforms:
@@ -1122,6 +1135,16 @@ To query based on a given dictionary key, use that key as the lookup name:
>>> Dog.objects.filter(data__breed="collie")
<QuerySet [<Dog: Meg>]>
To query a key for JSON ``null``, ``None`` or :class:`JSONNull()
<django.db.models.JSONNull>` can be used.
.. code-block:: pycon
>>> Dog.objects.filter(data__owner=None)
<Dog: Meg>
>>> Dog.objects.filter(data__owner=JSONNull())
<Dog: Meg>
Multiple keys can be chained together to form a path lookup:
.. code-block:: pycon