summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-06-26 05:34:26 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-06-26 05:34:26 +0000
commite41df5adccef0e32d4b8b877ec83e9dd271c1ccf (patch)
tree4ab2adae796351f3c294f4c7923f321d5cef304f
parent2c08986f44a52e3bbd5cb1fb9fd6b2b5a80941e3 (diff)
Fixed #7076 -- Include NULL values when excluding non-NULL items.
Based on a patch from emulbreh. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7760 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/sql/query.py26
-rw-r--r--tests/regressiontests/queries/models.py6
2 files changed, 24 insertions, 8 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index e3e3585a8e..b30c6a355c 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1045,17 +1045,27 @@ class Query(object):
self.promote_alias(table)
self.where.add((alias, col, field, lookup_type, value), connector)
+
if negate:
for alias in join_list:
self.promote_alias(alias)
- if final > 1 and lookup_type != 'isnull':
- for alias in join_list:
- if self.alias_map[alias] == self.LOUTER:
- j_col = self.alias_map[alias][RHS_JOIN_COL]
- entry = Node([(alias, j_col, None, 'isnull', True)])
- entry.negate()
- self.where.add(entry, AND)
- break
+ if lookup_type != 'isnull':
+ if final > 1:
+ for alias in join_list:
+ if self.alias_map[alias][JOIN_TYPE] == self.LOUTER:
+ j_col = self.alias_map[alias][RHS_JOIN_COL]
+ entry = Node([(alias, j_col, None, 'isnull', True)])
+ entry.negate()
+ self.where.add(entry, AND)
+ break
+ elif not (lookup_type == 'in' and not value):
+ # Leaky abstraction artifact: We have to specifically
+ # exclude the "foo__in=[]" case from this handling, because
+ # it's short-circuited in the Where class.
+ entry = Node([(alias, col, field, 'isnull', True)])
+ entry.negate()
+ self.where.add(entry, AND)
+
if can_reuse is not None:
can_reuse.update(join_list)
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index 8059798f86..d7c8fba9c6 100644
--- a/tests/regressiontests/queries/models.py
+++ b/tests/regressiontests/queries/models.py
@@ -756,5 +756,11 @@ select_related(). We used to return the parent's Detail record here by mistake.
>>> obj.person.details.data
u'd2'
+Bug #7076 -- excluding shouldn't eliminate NULL entries.
+>>> Item.objects.exclude(modified=time1).order_by('name')
+[<Item: four>, <Item: three>, <Item: two>]
+>>> Tag.objects.exclude(parent__name=t1.name)
+[<Tag: t1>, <Tag: t4>, <Tag: t5>]
+
"""}