Loading django/db/models/sql/query.py +1 −1 Original line number Diff line number Diff line Loading @@ -1031,7 +1031,7 @@ class Query(object): # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all # uses of None as a query value. if value is None: if lookup_type != 'exact': if lookup_type not in ('exact', 'iexact'): raise ValueError("Cannot use None as a query value") lookup_type = 'isnull' value = True Loading docs/ref/models/querysets.txt +6 −0 Original line number Diff line number Diff line Loading @@ -2028,9 +2028,15 @@ iexact Case-insensitive exact match. .. versionchanged:: 1.7 If the value provided for comparision is ``None``, it will be interpreted as an SQL ``NULL`` (see :lookup:`isnull` for more details). Example:: Blog.objects.get(name__iexact='beatles blog') Blog.objects.get(name__iexact=None) SQL equivalent:: Loading docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -450,6 +450,9 @@ Models argument to control whether or not to perform operations in bulk (i.e. using ``QuerySet.update()``). Defaults to ``True``. * It is now possible to use ``None`` as a query value for the :lookup:`iexact` lookup. Signals ^^^^^^^ Loading tests/null_queries/tests.py +7 −3 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ class NullQueriesTests(TestCase): """ Regression test for the use of None as a query value. None is interpreted as an SQL NULL, but only in __exact queries. None is interpreted as an SQL NULL, but only in __exact and __iexact queries. Set up some initial polls and choices """ p1 = Poll(question='Why?') Loading @@ -26,6 +27,9 @@ class NullQueriesTests(TestCase): # but every 'id' field has a value). self.assertQuerysetEqual(Choice.objects.filter(choice__exact=None), []) # The same behavior for iexact query. self.assertQuerysetEqual(Choice.objects.filter(choice__iexact=None), []) # Excluding the previous result returns everything. self.assertQuerysetEqual( Choice.objects.exclude(choice=None).order_by('id'), Loading @@ -38,10 +42,10 @@ class NullQueriesTests(TestCase): # Valid query, but fails because foo isn't a keyword self.assertRaises(FieldError, Choice.objects.filter, foo__exact=None) # Can't use None on anything other than __exact # Can't use None on anything other than __exact and __iexact self.assertRaises(ValueError, Choice.objects.filter, id__gt=None) # Can't use None on anything other than __exact # Can't use None on anything other than __exact and __iexact self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None) # Related managers use __exact=None implicitly if the object hasn't been saved. Loading Loading
django/db/models/sql/query.py +1 −1 Original line number Diff line number Diff line Loading @@ -1031,7 +1031,7 @@ class Query(object): # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all # uses of None as a query value. if value is None: if lookup_type != 'exact': if lookup_type not in ('exact', 'iexact'): raise ValueError("Cannot use None as a query value") lookup_type = 'isnull' value = True Loading
docs/ref/models/querysets.txt +6 −0 Original line number Diff line number Diff line Loading @@ -2028,9 +2028,15 @@ iexact Case-insensitive exact match. .. versionchanged:: 1.7 If the value provided for comparision is ``None``, it will be interpreted as an SQL ``NULL`` (see :lookup:`isnull` for more details). Example:: Blog.objects.get(name__iexact='beatles blog') Blog.objects.get(name__iexact=None) SQL equivalent:: Loading
docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -450,6 +450,9 @@ Models argument to control whether or not to perform operations in bulk (i.e. using ``QuerySet.update()``). Defaults to ``True``. * It is now possible to use ``None`` as a query value for the :lookup:`iexact` lookup. Signals ^^^^^^^ Loading
tests/null_queries/tests.py +7 −3 Original line number Diff line number Diff line Loading @@ -12,7 +12,8 @@ class NullQueriesTests(TestCase): """ Regression test for the use of None as a query value. None is interpreted as an SQL NULL, but only in __exact queries. None is interpreted as an SQL NULL, but only in __exact and __iexact queries. Set up some initial polls and choices """ p1 = Poll(question='Why?') Loading @@ -26,6 +27,9 @@ class NullQueriesTests(TestCase): # but every 'id' field has a value). self.assertQuerysetEqual(Choice.objects.filter(choice__exact=None), []) # The same behavior for iexact query. self.assertQuerysetEqual(Choice.objects.filter(choice__iexact=None), []) # Excluding the previous result returns everything. self.assertQuerysetEqual( Choice.objects.exclude(choice=None).order_by('id'), Loading @@ -38,10 +42,10 @@ class NullQueriesTests(TestCase): # Valid query, but fails because foo isn't a keyword self.assertRaises(FieldError, Choice.objects.filter, foo__exact=None) # Can't use None on anything other than __exact # Can't use None on anything other than __exact and __iexact self.assertRaises(ValueError, Choice.objects.filter, id__gt=None) # Can't use None on anything other than __exact # Can't use None on anything other than __exact and __iexact self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None) # Related managers use __exact=None implicitly if the object hasn't been saved. Loading