summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/sql/query.py2
-rw-r--r--tests/null_queries/models.py2
-rw-r--r--tests/null_queries/tests.py14
3 files changed, 15 insertions, 3 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 8fffce5dec..e3e6100f24 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1444,7 +1444,7 @@ class Query(BaseExpression):
# DEFAULT_DB_ALIAS isn't nice but it's the best that can be done here.
# A similar thing is done in is_nullable(), too.
if (
- lookup_name == "exact"
+ lookup_name in ("exact", "iexact")
and lookup.rhs == ""
and connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls
):
diff --git a/tests/null_queries/models.py b/tests/null_queries/models.py
index 2ed7fef2cc..6259ab55c6 100644
--- a/tests/null_queries/models.py
+++ b/tests/null_queries/models.py
@@ -7,7 +7,7 @@ class Poll(models.Model):
class Choice(models.Model):
poll = models.ForeignKey(Poll, models.CASCADE)
- choice = models.CharField(max_length=200)
+ choice = models.CharField(max_length=200, null=True)
# A set of models with an inner one pointing to two outer ones.
diff --git a/tests/null_queries/tests.py b/tests/null_queries/tests.py
index 828c68d921..9c061ae323 100644
--- a/tests/null_queries/tests.py
+++ b/tests/null_queries/tests.py
@@ -1,5 +1,5 @@
from django.core.exceptions import FieldError
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from .models import Choice, Inner, OuterA, OuterB, Poll
@@ -44,6 +44,18 @@ class NullQueriesTests(TestCase):
with self.assertRaisesMessage(ValueError, "Cannot use None as a query value"):
Choice.objects.filter(id__gt=None)
+ @skipUnlessDBFeature("interprets_empty_strings_as_nulls")
+ def test_empty_string_is_null(self):
+ p = Poll.objects.create(question="?")
+ c1 = Choice.objects.create(poll=p, choice=None)
+ c2 = Choice.objects.create(poll=p, choice="")
+ cases = [{"choice__exact": ""}, {"choice__iexact": ""}]
+ for lookup in cases:
+ with self.subTest(lookup):
+ self.assertSequenceEqual(
+ Choice.objects.filter(**lookup).order_by("id"), [c1, c2]
+ )
+
def test_unsaved(self):
poll = Poll(question="How?")
msg = (