Ticket #12855: django-extra-where.diff

File django-extra-where.diff, 5.4 KB (added by Alex, 5 years ago)
  • django/db/models/sql/compiler.py

    diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
    index 1625a0e..f364b1d 100644
    a b class SQLCompiler(object): 
    8484        if where:
    8585            result.append('WHERE %s' % where)
    8686            params.extend(w_params)
    87         if self.query.extra_where:
    88             if not where:
    89                 result.append('WHERE')
    90             else:
    91                 result.append('AND')
    92             result.append(' AND '.join(self.query.extra_where))
    9387
    9488        grouping, gb_params = self.get_grouping()
    9589        if grouping:
    class SQLCompiler(object): 
    124118                        result.append('LIMIT %d' % val)
    125119                result.append('OFFSET %d' % self.query.low_mark)
    126120
    127         params.extend(self.query.extra_params)
    128121        return ' '.join(result), tuple(params)
    129122
    130123    def as_nested_sql(self):
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index dde1494..2d3f610 100644
    a b from django.db.models.sql import aggregates as base_aggregates_module 
    1919from django.db.models.sql.constants import *
    2020from django.db.models.sql.datastructures import EmptyResultSet, Empty, MultiJoin
    2121from django.db.models.sql.expressions import SQLEvaluator
    22 from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR
     22from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
     23    ExtraWhere, AND, OR)
    2324from django.core.exceptions import FieldError
    2425
    2526__all__ = ['Query', 'RawQuery']
    class Query(object): 
    128129        self._extra_select_cache = None
    129130
    130131        self.extra_tables = ()
    131         self.extra_where = ()
    132         self.extra_params = ()
    133132        self.extra_order_by = ()
    134133
    135134        # A tuple that is a set of model field names and either True, if these
    class Query(object): 
    256255        else:
    257256            obj._extra_select_cache = self._extra_select_cache.copy()
    258257        obj.extra_tables = self.extra_tables
    259         obj.extra_where = self.extra_where
    260         obj.extra_params = self.extra_params
    261258        obj.extra_order_by = self.extra_order_by
    262259        obj.deferred_loading = deepcopy(self.deferred_loading)
    263260        if self.filter_is_sticky and self.used_aliases:
    class Query(object): 
    466463            if self.extra and rhs.extra:
    467464                raise ValueError("When merging querysets using 'or', you "
    468465                        "cannot have extra(select=...) on both sides.")
    469             if self.extra_where and rhs.extra_where:
    470                 raise ValueError("When merging querysets using 'or', you "
    471                         "cannot have extra(where=...) on both sides.")
    472466        self.extra.update(rhs.extra)
    473467        extra_select_mask = set()
    474468        if self.extra_select_mask is not None:
    class Query(object): 
    478472        if extra_select_mask:
    479473            self.set_extra_mask(extra_select_mask)
    480474        self.extra_tables += rhs.extra_tables
    481         self.extra_where += rhs.extra_where
    482         self.extra_params += rhs.extra_params
    483475
    484476        # Ordering uses the 'rhs' ordering, unless it has none, in which case
    485477        # the current ordering is used.
    class Query(object): 
    16111603                select_pairs[name] = (entry, entry_params)
    16121604            # This is order preserving, since self.extra_select is a SortedDict.
    16131605            self.extra.update(select_pairs)
    1614         if where:
    1615             self.extra_where += tuple(where)
    1616         if params:
    1617             self.extra_params += tuple(params)
     1606        if where or params:
     1607            self.where.add(ExtraWhere(where, params), AND)
    16181608        if tables:
    16191609            self.extra_tables += tuple(tables)
    16201610        if order_by:
  • django/db/models/sql/where.py

    diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
    index 4aa2351..cf147c6 100644
    a b class WhereNode(tree.Node): 
    220220                child.relabel_aliases(change_map)
    221221            elif isinstance(child, tree.Node):
    222222                self.relabel_aliases(change_map, child)
    223             else:
     223            elif isinstance(child, (list, tuple)):
    224224                if isinstance(child[0], (list, tuple)):
    225225                    elt = list(child[0])
    226226                    if elt[0] in change_map:
    class NothingNode(object): 
    254254    def relabel_aliases(self, change_map, node=None):
    255255        return
    256256
     257class ExtraWhere(object):
     258    def __init__(self, sqls, params):
     259        self.sqls = sqls
     260        self.params = params
     261   
     262    def as_sql(self, qn=None, connection=None):
     263        return " AND ".join(self.sqls), tuple(self.params or ())
     264
    257265class Constraint(object):
    258266    """
    259267    An object that can be passed to WhereNode.add() and knows how to
  • tests/regressiontests/extra_regress/models.py

    diff --git a/tests/regressiontests/extra_regress/models.py b/tests/regressiontests/extra_regress/models.py
    index d4d7cb8..1e94de0 100644
    a b True 
    210210>>> TestObject.objects.filter(pk__in=TestObject.objects.values('pk').extra(select={'extra': 1}))
    211211[<TestObject: TestObject: first,second,third>]
    212212
     213>>> pk = TestObject.objects.get().pk
     214>>> TestObject.objects.filter(pk=pk) | TestObject.objects.extra(where=["id > %s"], params=[pk])
     215[<TestObject: TestObject: first,second,third>]
     216
    213217"""}
Back to Top