Skip to content

Commit

Permalink
queryset-refactor: Added the ability to use a subclass of WhereNode i…
Browse files Browse the repository at this point in the history
…n queries. Also allow extension of the permitted lookup terms. Both of these are drive by geo-django requirements, but should be generally useful. Thanks, Justin Bronn.

Fixed #6261.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7031 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Jan 27, 2008
1 parent dd2251a commit e016a4f
Showing 1 changed file with 14 additions and 11 deletions.
25 changes: 14 additions & 11 deletions django/db/models/sql/query.py
Expand Up @@ -77,8 +77,9 @@ class Query(object):
LOUTER = 'LEFT OUTER JOIN'

alias_prefix = 'T'
query_terms = QUERY_TERMS

def __init__(self, model, connection):
def __init__(self, model, connection, where=WhereNode):
self.model = model
self.connection = connection
self.alias_map = {} # Maps alias to table name
Expand All @@ -91,7 +92,8 @@ def __init__(self, model, connection):
# SQL-related attributes
self.select = []
self.tables = [] # Aliases in the order they are created.
self.where = WhereNode()
self.where = where()
self.where_class = where
self.group_by = []
self.having = []
self.order_by = []
Expand Down Expand Up @@ -156,6 +158,7 @@ def clone(self, klass=None, **kwargs):
obj.select = self.select[:]
obj.tables = self.tables[:]
obj.where = copy.deepcopy(self.where)
obj.where_class = self.where_class
obj.group_by = self.group_by[:]
obj.having = self.having[:]
obj.order_by = self.order_by[:]
Expand Down Expand Up @@ -192,7 +195,7 @@ def get_count(self):
obj.clear_limits()
obj.select_related = False
if obj.distinct and len(obj.select) > 1:
obj = self.clone(CountQuery, _query=obj, where=WhereNode(),
obj = self.clone(CountQuery, _query=obj, where=self.where_class(),
distinct=False)
obj.select = []
obj.extra_select = SortedDict()
Expand Down Expand Up @@ -319,12 +322,12 @@ def combine(self, rhs, connector):
elif self.where:
# rhs has an empty where clause. Make it match everything (see
# above for reasoning).
w = WhereNode()
w = self.where_class()
alias = self.join((None, self.model._meta.db_table, None, None))
pk = self.model._meta.pk
w.add(EverythingNode(), AND)
else:
w = WhereNode()
w = self.where_class()
self.where.add(w, connector)

# Selection columns and extra extensions are those provided by 'rhs'.
Expand Down Expand Up @@ -704,7 +707,7 @@ def add_filter(self, filter_expr, connector=AND, negate=False):
raise TypeError("Cannot parse keyword query %r" % arg)

# Work out the lookup type and remove it from 'parts', if necessary.
if len(parts) == 1 or parts[-1] not in QUERY_TERMS:
if len(parts) == 1 or parts[-1] not in self.query_terms:
lookup_type = 'exact'
else:
lookup_type = parts.pop()
Expand Down Expand Up @@ -1109,22 +1112,22 @@ def delete_batch_related(self, pk_list):
for related in cls._meta.get_all_related_many_to_many_objects():
if not isinstance(related.field, generic.GenericRelation):
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = WhereNode()
where = self.where_class()
where.add((None, related.field.m2m_reverse_name(),
related.field, 'in',
pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]),
AND)
self.do_query(related.field.m2m_db_table(), where)

for f in cls._meta.many_to_many:
w1 = WhereNode()
w1 = self.where_class()
if isinstance(f, generic.GenericRelation):
from django.contrib.contenttypes.models import ContentType
field = f.rel.to._meta.get_field(f.content_type_field_name)
w1.add((None, field.column, field, 'exact',
ContentType.objects.get_for_model(cls).id), AND)
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = WhereNode()
where = self.where_class()
where.add((None, f.m2m_column_name(), f, 'in',
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
AND)
Expand All @@ -1141,7 +1144,7 @@ def delete_batch(self, pk_list):
lot of values in pk_list.
"""
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = WhereNode()
where = self.where_class()
field = self.model._meta.pk
where.add((None, field.column, field, 'in',
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND)
Expand Down Expand Up @@ -1185,7 +1188,7 @@ def clear_related(self, related_field, pk_list):
This is used by the QuerySet.delete_objects() method.
"""
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = WhereNode()
where = self.where_class()
f = self.model._meta.pk
where.add((None, f.column, f, 'in',
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
Expand Down

0 comments on commit e016a4f

Please sign in to comment.