mirror of
https://github.com/django/django.git
synced 2025-10-23 21:59:11 +00:00
Simplified QuerySet field.null handling
QuerySet had previously some complex logic for dealing with nullable fields in negated add_filter() calls. It seems the logic is leftover from a time where the WhereNode wasn't as intelligent in handling field__in=[] conditions. Thanks to aaugustin for comments on the patch.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import datetime
|
||||
from operator import attrgetter
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
@@ -18,7 +19,7 @@ from .models import (Annotation, Article, Author, Celebrity, Child, Cover,
|
||||
ManagedModel, Member, NamedCategory, Note, Number, Plaything, PointerA,
|
||||
Ranking, Related, Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten,
|
||||
Node, ObjectA, ObjectB, ObjectC, CategoryItem, SimpleCategory,
|
||||
SpecialCategory, OneToOneCategory)
|
||||
SpecialCategory, OneToOneCategory, NullableName)
|
||||
|
||||
|
||||
class BaseQuerysetTest(TestCase):
|
||||
@@ -1894,3 +1895,38 @@ class DefaultValuesInsertTest(TestCase):
|
||||
DumbCategory.objects.create()
|
||||
except TypeError:
|
||||
self.fail("Creation of an instance of a model with only the PK field shouldn't error out after bulk insert refactoring (#17056)")
|
||||
|
||||
class NullInExcludeTest(TestCase):
|
||||
def setUp(self):
|
||||
NullableName.objects.create(name='i1')
|
||||
NullableName.objects.create()
|
||||
|
||||
def test_null_in_exclude_qs(self):
|
||||
none_val = '' if connection.features.interprets_empty_strings_as_nulls else None
|
||||
self.assertQuerysetEqual(
|
||||
NullableName.objects.exclude(name__in=[]),
|
||||
['i1', none_val], attrgetter('name'))
|
||||
self.assertQuerysetEqual(
|
||||
NullableName.objects.exclude(name__in=['i1']),
|
||||
[none_val], attrgetter('name'))
|
||||
self.assertQuerysetEqual(
|
||||
NullableName.objects.exclude(name__in=['i3']),
|
||||
['i1', none_val], attrgetter('name'))
|
||||
inner_qs = NullableName.objects.filter(name='i1').values_list('name')
|
||||
self.assertQuerysetEqual(
|
||||
NullableName.objects.exclude(name__in=inner_qs),
|
||||
[none_val], attrgetter('name'))
|
||||
# Check that the inner queryset wasn't executed - it should be turned
|
||||
# into subquery above
|
||||
self.assertIs(inner_qs._result_cache, None)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_col_not_in_list_containing_null(self):
|
||||
"""
|
||||
The following case is not handled properly because
|
||||
SQL's COL NOT IN (list containing null) handling is too weird to
|
||||
abstract away.
|
||||
"""
|
||||
self.assertQuerysetEqual(
|
||||
NullableName.objects.exclude(name__in=[None]),
|
||||
['i1'], attrgetter('name'))
|
||||
|
||||
Reference in New Issue
Block a user