Author: jbronn
Date: 2010-02-22 22:39:39 -0600 (Mon, 22 Feb 2010)
New Revision: 12502

Modified:
   django/trunk/django/db/models/sql/compiler.py
   django/trunk/django/db/models/sql/query.py
   django/trunk/django/db/models/sql/where.py
   django/trunk/tests/regressiontests/extra_regress/models.py
Log:
Fixed #12855 -- QuerySets with `extra` where parameters now combine correctly.  
Thanks, Alex Gaynor.


Modified: django/trunk/django/db/models/sql/compiler.py
===================================================================
--- django/trunk/django/db/models/sql/compiler.py       2010-02-23 00:08:03 UTC 
(rev 12501)
+++ django/trunk/django/db/models/sql/compiler.py       2010-02-23 04:39:39 UTC 
(rev 12502)
@@ -84,12 +84,6 @@
         if where:
             result.append('WHERE %s' % where)
             params.extend(w_params)
-        if self.query.extra_where:
-            if not where:
-                result.append('WHERE')
-            else:
-                result.append('AND')
-            result.append(' AND '.join(self.query.extra_where))
 
         grouping, gb_params = self.get_grouping()
         if grouping:
@@ -124,7 +118,6 @@
                         result.append('LIMIT %d' % val)
                 result.append('OFFSET %d' % self.query.low_mark)
 
-        params.extend(self.query.extra_params)
         return ' '.join(result), tuple(params)
 
     def as_nested_sql(self):

Modified: django/trunk/django/db/models/sql/query.py
===================================================================
--- django/trunk/django/db/models/sql/query.py  2010-02-23 00:08:03 UTC (rev 
12501)
+++ django/trunk/django/db/models/sql/query.py  2010-02-23 04:39:39 UTC (rev 
12502)
@@ -19,7 +19,8 @@
 from django.db.models.sql.constants import *
 from django.db.models.sql.datastructures import EmptyResultSet, Empty, 
MultiJoin
 from django.db.models.sql.expressions import SQLEvaluator
-from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, 
AND, OR
+from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
+    ExtraWhere, AND, OR)
 from django.core.exceptions import FieldError
 
 __all__ = ['Query', 'RawQuery']
@@ -128,8 +129,6 @@
         self._extra_select_cache = None
 
         self.extra_tables = ()
-        self.extra_where = ()
-        self.extra_params = ()
         self.extra_order_by = ()
 
         # A tuple that is a set of model field names and either True, if these
@@ -256,8 +255,6 @@
         else:
             obj._extra_select_cache = self._extra_select_cache.copy()
         obj.extra_tables = self.extra_tables
-        obj.extra_where = self.extra_where
-        obj.extra_params = self.extra_params
         obj.extra_order_by = self.extra_order_by
         obj.deferred_loading = deepcopy(self.deferred_loading)
         if self.filter_is_sticky and self.used_aliases:
@@ -466,9 +463,6 @@
             if self.extra and rhs.extra:
                 raise ValueError("When merging querysets using 'or', you "
                         "cannot have extra(select=...) on both sides.")
-            if self.extra_where and rhs.extra_where:
-                raise ValueError("When merging querysets using 'or', you "
-                        "cannot have extra(where=...) on both sides.")
         self.extra.update(rhs.extra)
         extra_select_mask = set()
         if self.extra_select_mask is not None:
@@ -478,8 +472,6 @@
         if extra_select_mask:
             self.set_extra_mask(extra_select_mask)
         self.extra_tables += rhs.extra_tables
-        self.extra_where += rhs.extra_where
-        self.extra_params += rhs.extra_params
 
         # Ordering uses the 'rhs' ordering, unless it has none, in which case
         # the current ordering is used.
@@ -1611,10 +1603,8 @@
                 select_pairs[name] = (entry, entry_params)
             # This is order preserving, since self.extra_select is a 
SortedDict.
             self.extra.update(select_pairs)
-        if where:
-            self.extra_where += tuple(where)
-        if params:
-            self.extra_params += tuple(params)
+        if where or params:
+            self.where.add(ExtraWhere(where, params), AND)
         if tables:
             self.extra_tables += tuple(tables)
         if order_by:

Modified: django/trunk/django/db/models/sql/where.py
===================================================================
--- django/trunk/django/db/models/sql/where.py  2010-02-23 00:08:03 UTC (rev 
12501)
+++ django/trunk/django/db/models/sql/where.py  2010-02-23 04:39:39 UTC (rev 
12502)
@@ -220,7 +220,7 @@
                 child.relabel_aliases(change_map)
             elif isinstance(child, tree.Node):
                 self.relabel_aliases(change_map, child)
-            else:
+            elif isinstance(child, (list, tuple)):
                 if isinstance(child[0], (list, tuple)):
                     elt = list(child[0])
                     if elt[0] in change_map:
@@ -254,6 +254,14 @@
     def relabel_aliases(self, change_map, node=None):
         return
 
+class ExtraWhere(object):
+    def __init__(self, sqls, params):
+        self.sqls = sqls
+        self.params = params
+    
+    def as_sql(self, qn=None, connection=None):
+        return " AND ".join(self.sqls), tuple(self.params or ())
+
 class Constraint(object):
     """
     An object that can be passed to WhereNode.add() and knows how to

Modified: django/trunk/tests/regressiontests/extra_regress/models.py
===================================================================
--- django/trunk/tests/regressiontests/extra_regress/models.py  2010-02-23 
00:08:03 UTC (rev 12501)
+++ django/trunk/tests/regressiontests/extra_regress/models.py  2010-02-23 
04:39:39 UTC (rev 12502)
@@ -210,4 +210,8 @@
 >>> TestObject.objects.filter(pk__in=TestObject.objects.values('pk').extra(select={'extra':
 >>>  1}))
 [<TestObject: TestObject: first,second,third>]
 
+>>> pk = TestObject.objects.get().pk
+>>> TestObject.objects.filter(pk=pk) | TestObject.objects.extra(where=["id > 
%s"], params=[pk])
+[<TestObject: TestObject: first,second,third>]
+
 """}

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to