Commit 6a28f581 authored by Justin Bronn's avatar Justin Bronn
Browse files

Fixed #12855 -- QuerySets? with extra where parameters now combine correctly. Thanks, Alex Gaynor.

Backport of r12502 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12507 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 16efc1a9
Loading
Loading
Loading
Loading
+4 −21
Original line number Diff line number Diff line
@@ -18,7 +18,8 @@ from django.db.models.fields import FieldDoesNotExist
from django.db.models.query_utils import select_related_descend
from django.db.models.sql import aggregates as base_aggregates_module
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
from datastructures import EmptyResultSet, Empty, MultiJoin
from constants import *
@@ -92,8 +93,6 @@ class BaseQuery(object):
        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
@@ -232,8 +231,6 @@ class BaseQuery(object):
        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:
@@ -418,12 +415,6 @@ class BaseQuery(object):
        if where:
            result.append('WHERE %s' % where)
            params.extend(w_params)
        if self.extra_where:
            if not where:
                result.append('WHERE')
            else:
                result.append('AND')
            result.append(' AND '.join(self.extra_where))

        grouping, gb_params = self.get_grouping()
        if grouping:
@@ -458,7 +449,6 @@ class BaseQuery(object):
                        result.append('LIMIT %d' % val)
                result.append('OFFSET %d' % self.low_mark)

        params.extend(self.extra_params)
        return ' '.join(result), tuple(params)

    def as_nested_sql(self):
@@ -553,9 +543,6 @@ class BaseQuery(object):
            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:
@@ -565,8 +552,6 @@ class BaseQuery(object):
        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.
@@ -2181,10 +2166,8 @@ class BaseQuery(object):
                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:
+9 −1
Original line number Diff line number Diff line
@@ -216,7 +216,7 @@ class WhereNode(tree.Node):
                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:
@@ -249,6 +249,14 @@ class NothingNode(object):
    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):
        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
+4 −0
Original line number Diff line number Diff line
@@ -208,4 +208,8 @@ True
>>> 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>]

"""}