summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Gama <cliffygamy@gmail.com>2026-03-01 13:46:17 +0200
committerJacob Walls <jacobtylerwalls@gmail.com>2026-03-02 10:32:44 -0500
commitffa1dad378927396a5593cd9865c3f751fa59059 (patch)
tree06f3eade3b2e3ede63329f6d6af31d9399ca41ef
parent202eca7795710c82cd64a248650afc64f905a17e (diff)
Refs #35381 -- Moved JSONNull to django.db.models.expressions.
-rw-r--r--django/db/models/__init__.py3
-rw-r--r--django/db/models/expressions.py24
-rw-r--r--django/db/models/fields/json.py29
3 files changed, 30 insertions, 26 deletions
diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py
index b8f95526f7..c5803929c5 100644
--- a/django/db/models/__init__.py
+++ b/django/db/models/__init__.py
@@ -28,6 +28,7 @@ from django.db.models.expressions import (
ExpressionWrapper,
F,
Func,
+ JSONNull,
OrderBy,
OuterRef,
RowRange,
@@ -45,7 +46,7 @@ from django.db.models.fields import __all__ as fields_all
from django.db.models.fields.composite import CompositePrimaryKey
from django.db.models.fields.files import FileField, ImageField
from django.db.models.fields.generated import GeneratedField
-from django.db.models.fields.json import JSONField, JSONNull
+from django.db.models.fields.json import JSONField
from django.db.models.fields.proxy import OrderWrt
from django.db.models.indexes import * # NOQA
from django.db.models.indexes import __all__ as indexes_all
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index d0e91f13d2..9d3c1241e7 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1233,6 +1233,30 @@ class Value(Expression):
return self.value
+@deconstructible(path="django.db.models.JSONNull")
+class JSONNull(Value):
+ """Represent JSON `null` primitive."""
+
+ def __init__(self):
+ from django.db.models import JSONField
+
+ super().__init__(None, output_field=JSONField())
+
+ def __repr__(self):
+ return f"{self.__class__.__name__}()"
+
+ def as_sql(self, compiler, connection):
+ value = self.output_field.get_db_prep_value(self.value, connection)
+ if value is None:
+ value = "null"
+ return "%s", (value,)
+
+ def as_mysql(self, compiler, connection):
+ sql, params = self.as_sql(compiler, connection)
+ sql = "JSON_EXTRACT(%s, '$')"
+ return sql, params
+
+
class RawSQL(Expression):
allowed_default = True
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py
index cf4f5953a7..ed7b4d26a6 100644
--- a/django/db/models/fields/json.py
+++ b/django/db/models/fields/json.py
@@ -12,7 +12,6 @@ from django.db.models.lookups import (
PostgresOperatorLookup,
Transform,
)
-from django.utils.deconstruct import deconstructible
from django.utils.deprecation import RemovedInDjango70Warning, django_file_prefixes
from django.utils.translation import gettext_lazy as _
@@ -151,28 +150,6 @@ class JSONField(CheckFieldDefaultMixin, Field):
)
-@deconstructible(path="django.db.models.JSONNull")
-class JSONNull(expressions.Value):
- """Represent JSON `null` primitive."""
-
- def __init__(self):
- super().__init__(None, output_field=JSONField())
-
- def __repr__(self):
- return f"{self.__class__.__name__}()"
-
- def as_sql(self, compiler, connection):
- value = self.output_field.get_db_prep_value(self.value, connection)
- if value is None:
- value = "null"
- return "%s", (value,)
-
- def as_mysql(self, compiler, connection):
- sql, params = self.as_sql(compiler, connection)
- sql = "JSON_EXTRACT(%s, '$')"
- return sql, params
-
-
class DataContains(FieldGetDbPrepValueMixin, PostgresOperatorLookup):
lookup_name = "contains"
postgres_operator = "@>"
@@ -357,7 +334,9 @@ class JSONExact(lookups.Exact):
# Treat None lookup values as null.
if rhs == "%s" and (*rhs_params,) == (None,):
rhs_params = ("null",)
- if connection.vendor == "mysql" and not isinstance(self.rhs, JSONNull):
+ if connection.vendor == "mysql" and not isinstance(
+ self.rhs, expressions.JSONNull
+ ):
func = ["JSON_EXTRACT(%s, '$')"] * len(rhs_params)
rhs %= tuple(func)
return rhs, rhs_params
@@ -464,7 +443,7 @@ class JSONIn(ProcessJSONLHSMixin, lookups.In):
if (
connection.features.supports_primitives_in_json_field
and isinstance(self.rhs, expressions.ExpressionList)
- and JSONNull() in self.rhs.get_source_expressions()
+ and expressions.JSONNull() in self.rhs.get_source_expressions()
):
# Break the lookup into multiple exact lookups combined with OR, as
# Oracle does not support directly extracting JSON scalar null as a