Fixed #36508 -- Interpreted __iexact=None on KeyTransforms as __exact=None.

Thanks Jacob Walls for the report.
This commit is contained in:
Clifford Gama
2025-10-25 18:41:08 +02:00
committed by Jacob Walls
parent 9cc5c87ffb
commit 6ee8e9d56c
3 changed files with 24 additions and 1 deletions

View File

@@ -665,7 +665,19 @@ class KeyTransformExact(JSONExact):
class KeyTransformIExact(
CaseInsensitiveMixin, KeyTransformTextLookupMixin, lookups.IExact
):
pass
can_use_none_as_rhs = True
def as_sql(self, compiler, connection):
if self.rhs is None:
# Interpret __iexact=None on KeyTextTransform as __exact=None on
# KeyTransform.
keytransform = KeyTransform(self.lhs.key_name, self.lhs.lhs)
exact_lookup = keytransform.get_lookup("exact")(keytransform, self.rhs)
# Delegate to the backend vendor method, if it exists.
vendor = connection.vendor
as_vendor = getattr(exact_lookup, f"as_{vendor}", exact_lookup.as_sql)
return as_vendor(compiler, connection)
return super().as_sql(compiler, connection)
class KeyTransformIContains(

View File

@@ -400,6 +400,11 @@ Miscellaneous
* The minimum supported version of SQLite is increased from 3.31.0 to 3.37.0.
* The :lookup:`iexact=None <iexact>` lookup on
:class:`~django.db.models.JSONField` key transforms now matches JSON
``null``, to match the behavior of :lookup:`exact=None <exact>` on key
transforms. Previously, it was interpreted as an :lookup:`isnull` lookup.
.. _deprecated-features-6.1:
Features deprecated in 6.1

View File

@@ -782,6 +782,12 @@ class TestQuerying(TestCase):
[self.objs[4]],
)
def test_key_iexact_none(self):
self.assertSequenceEqual(
NullableJSONModel.objects.filter(value__j__iexact=None),
[self.objs[4]],
)
def test_none_key_exclude(self):
obj = NullableJSONModel.objects.create(value={"j": 1})
if connection.vendor == "oracle":