From 0baea920c865ae2d40a4e1d9281e25327fc0dbe5 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Mon, 31 Jul 2017 01:01:45 +0500 Subject: [PATCH] Fixed #28453 -- Made __exact=None lookup use transforms. --- django/db/models/sql/query.py | 3 ++- tests/lookup/models.py | 11 +++++++++++ tests/lookup/tests.py | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 48bbd7c851..5e262d1765 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -984,7 +984,8 @@ class Query: if value is None: if lookups[-1] not in ('exact', 'iexact'): raise ValueError("Cannot use None as a query value") - return True, ['isnull'], used_joins + lookups[-1] = 'isnull' + return True, lookups, used_joins elif hasattr(value, 'resolve_expression'): pre_joins = self.alias_refcount.copy() value = value.resolve_expression(self, reuse=can_reuse, allow_joins=allow_joins) diff --git a/tests/lookup/models.py b/tests/lookup/models.py index 2fa5b87755..1c7ea799a6 100644 --- a/tests/lookup/models.py +++ b/tests/lookup/models.py @@ -43,9 +43,20 @@ class Tag(models.Model): ordering = ('name', ) +class NulledTextField(models.TextField): + pass + + +@NulledTextField.register_lookup +class NulledTransform(models.Transform): + lookup_name = 'nulled' + template = 'NULL' + + class Season(models.Model): year = models.PositiveSmallIntegerField() gt = models.IntegerField(null=True, blank=True) + nulled_text_field = NulledTextField(null=True) def __str__(self): return str(self.year) diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py index 41270cd19f..37e98f43e2 100644 --- a/tests/lookup/tests.py +++ b/tests/lookup/tests.py @@ -839,3 +839,10 @@ class LookupTests(TestCase): ''], ordered=False ) + + def test_exact_none_transform(self): + """Transforms are used for __exact=None.""" + Season.objects.create(year=1, nulled_text_field='not null') + self.assertFalse(Season.objects.filter(nulled_text_field__isnull=True)) + self.assertTrue(Season.objects.filter(nulled_text_field__nulled__isnull=True)) + self.assertTrue(Season.objects.filter(nulled_text_field__nulled__exact=None))