Skip to content

Commit 4ce4ed7

Browse files
JaeHyuck Sajacobtylerwalls
authored andcommitted
Fixed #36821 -- Treated empty strings as NULL for iexact lookups on Oracle.
Signed-off-by: JaeHyuck Sa <wogur981208@gmail.com>
1 parent 6a59637 commit 4ce4ed7

3 files changed

Lines changed: 15 additions & 3 deletions

File tree

django/db/models/sql/query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,7 @@ def build_lookup(self, lookups, lhs, rhs):
14441444
# DEFAULT_DB_ALIAS isn't nice but it's the best that can be done here.
14451445
# A similar thing is done in is_nullable(), too.
14461446
if (
1447-
lookup_name == "exact"
1447+
lookup_name in ("exact", "iexact")
14481448
and lookup.rhs == ""
14491449
and connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls
14501450
):

tests/null_queries/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class Poll(models.Model):
77

88
class Choice(models.Model):
99
poll = models.ForeignKey(Poll, models.CASCADE)
10-
choice = models.CharField(max_length=200)
10+
choice = models.CharField(max_length=200, null=True)
1111

1212

1313
# A set of models with an inner one pointing to two outer ones.

tests/null_queries/tests.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from django.core.exceptions import FieldError
2-
from django.test import TestCase
2+
from django.test import TestCase, skipUnlessDBFeature
33

44
from .models import Choice, Inner, OuterA, OuterB, Poll
55

@@ -44,6 +44,18 @@ def test_none_as_null(self):
4444
with self.assertRaisesMessage(ValueError, "Cannot use None as a query value"):
4545
Choice.objects.filter(id__gt=None)
4646

47+
@skipUnlessDBFeature("interprets_empty_strings_as_nulls")
48+
def test_empty_string_is_null(self):
49+
p = Poll.objects.create(question="?")
50+
c1 = Choice.objects.create(poll=p, choice=None)
51+
c2 = Choice.objects.create(poll=p, choice="")
52+
cases = [{"choice__exact": ""}, {"choice__iexact": ""}]
53+
for lookup in cases:
54+
with self.subTest(lookup):
55+
self.assertSequenceEqual(
56+
Choice.objects.filter(**lookup).order_by("id"), [c1, c2]
57+
)
58+
4759
def test_unsaved(self):
4860
poll = Poll(question="How?")
4961
msg = (

0 commit comments

Comments
 (0)