Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
  • Loading branch information...
commit e41df5adccef0e32d4b8b877ec83e9dd271c1ccf 1 parent 2c08986
Malcolm Tredinnick authored June 26, 2008
26  django/db/models/sql/query.py
@@ -1045,17 +1045,27 @@ def add_filter(self, filter_expr, connector=AND, negate=False, trim=False,
1045 1045
                 self.promote_alias(table)
1046 1046
 
1047 1047
         self.where.add((alias, col, field, lookup_type, value), connector)
  1048
+
1048 1049
         if negate:
1049 1050
             for alias in join_list:
1050 1051
                 self.promote_alias(alias)
1051  
-            if final > 1 and lookup_type != 'isnull':
1052  
-                for alias in join_list:
1053  
-                    if self.alias_map[alias] == self.LOUTER:
1054  
-                        j_col = self.alias_map[alias][RHS_JOIN_COL]
1055  
-                        entry = Node([(alias, j_col, None, 'isnull', True)])
1056  
-                        entry.negate()
1057  
-                        self.where.add(entry, AND)
1058  
-                        break
  1052
+            if lookup_type != 'isnull':
  1053
+                if final > 1:
  1054
+                    for alias in join_list:
  1055
+                        if self.alias_map[alias][JOIN_TYPE] == self.LOUTER:
  1056
+                            j_col = self.alias_map[alias][RHS_JOIN_COL]
  1057
+                            entry = Node([(alias, j_col, None, 'isnull', True)])
  1058
+                            entry.negate()
  1059
+                            self.where.add(entry, AND)
  1060
+                            break
  1061
+                elif not (lookup_type == 'in' and not value):
  1062
+                    # Leaky abstraction artifact: We have to specifically
  1063
+                    # exclude the "foo__in=[]" case from this handling, because
  1064
+                    # it's short-circuited in the Where class.
  1065
+                    entry = Node([(alias, col, field, 'isnull', True)])
  1066
+                    entry.negate()
  1067
+                    self.where.add(entry, AND)
  1068
+
1059 1069
         if can_reuse is not None:
1060 1070
             can_reuse.update(join_list)
1061 1071
 
6  tests/regressiontests/queries/models.py
@@ -756,5 +756,11 @@ class Child(models.Model):
756 756
 >>> obj.person.details.data
757 757
 u'd2'
758 758
 
  759
+Bug #7076 -- excluding shouldn't eliminate NULL entries.
  760
+>>> Item.objects.exclude(modified=time1).order_by('name')
  761
+[<Item: four>, <Item: three>, <Item: two>]
  762
+>>> Tag.objects.exclude(parent__name=t1.name)
  763
+[<Tag: t1>, <Tag: t4>, <Tag: t5>]
  764
+
759 765
 """}
760 766
 

0 notes on commit e41df5a

Please sign in to comment.
Something went wrong with that request. Please try again.