mirror of
https://github.com/django/django.git
synced 2025-07-06 02:39:12 +00:00
queryset-refactor: Added the ability to use a subclass of WhereNode in 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
This commit is contained in:
parent
dd2251a653
commit
e016a4f987
@ -77,8 +77,9 @@ class Query(object):
|
|||||||
LOUTER = 'LEFT OUTER JOIN'
|
LOUTER = 'LEFT OUTER JOIN'
|
||||||
|
|
||||||
alias_prefix = 'T'
|
alias_prefix = 'T'
|
||||||
|
query_terms = QUERY_TERMS
|
||||||
|
|
||||||
def __init__(self, model, connection):
|
def __init__(self, model, connection, where=WhereNode):
|
||||||
self.model = model
|
self.model = model
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
self.alias_map = {} # Maps alias to table name
|
self.alias_map = {} # Maps alias to table name
|
||||||
@ -91,7 +92,8 @@ class Query(object):
|
|||||||
# SQL-related attributes
|
# SQL-related attributes
|
||||||
self.select = []
|
self.select = []
|
||||||
self.tables = [] # Aliases in the order they are created.
|
self.tables = [] # Aliases in the order they are created.
|
||||||
self.where = WhereNode()
|
self.where = where()
|
||||||
|
self.where_class = where
|
||||||
self.group_by = []
|
self.group_by = []
|
||||||
self.having = []
|
self.having = []
|
||||||
self.order_by = []
|
self.order_by = []
|
||||||
@ -156,6 +158,7 @@ class Query(object):
|
|||||||
obj.select = self.select[:]
|
obj.select = self.select[:]
|
||||||
obj.tables = self.tables[:]
|
obj.tables = self.tables[:]
|
||||||
obj.where = copy.deepcopy(self.where)
|
obj.where = copy.deepcopy(self.where)
|
||||||
|
obj.where_class = self.where_class
|
||||||
obj.group_by = self.group_by[:]
|
obj.group_by = self.group_by[:]
|
||||||
obj.having = self.having[:]
|
obj.having = self.having[:]
|
||||||
obj.order_by = self.order_by[:]
|
obj.order_by = self.order_by[:]
|
||||||
@ -192,7 +195,7 @@ class Query(object):
|
|||||||
obj.clear_limits()
|
obj.clear_limits()
|
||||||
obj.select_related = False
|
obj.select_related = False
|
||||||
if obj.distinct and len(obj.select) > 1:
|
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)
|
distinct=False)
|
||||||
obj.select = []
|
obj.select = []
|
||||||
obj.extra_select = SortedDict()
|
obj.extra_select = SortedDict()
|
||||||
@ -319,12 +322,12 @@ class Query(object):
|
|||||||
elif self.where:
|
elif self.where:
|
||||||
# rhs has an empty where clause. Make it match everything (see
|
# rhs has an empty where clause. Make it match everything (see
|
||||||
# above for reasoning).
|
# above for reasoning).
|
||||||
w = WhereNode()
|
w = self.where_class()
|
||||||
alias = self.join((None, self.model._meta.db_table, None, None))
|
alias = self.join((None, self.model._meta.db_table, None, None))
|
||||||
pk = self.model._meta.pk
|
pk = self.model._meta.pk
|
||||||
w.add(EverythingNode(), AND)
|
w.add(EverythingNode(), AND)
|
||||||
else:
|
else:
|
||||||
w = WhereNode()
|
w = self.where_class()
|
||||||
self.where.add(w, connector)
|
self.where.add(w, connector)
|
||||||
|
|
||||||
# Selection columns and extra extensions are those provided by 'rhs'.
|
# Selection columns and extra extensions are those provided by 'rhs'.
|
||||||
@ -704,7 +707,7 @@ class Query(object):
|
|||||||
raise TypeError("Cannot parse keyword query %r" % arg)
|
raise TypeError("Cannot parse keyword query %r" % arg)
|
||||||
|
|
||||||
# Work out the lookup type and remove it from 'parts', if necessary.
|
# 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'
|
lookup_type = 'exact'
|
||||||
else:
|
else:
|
||||||
lookup_type = parts.pop()
|
lookup_type = parts.pop()
|
||||||
@ -1109,7 +1112,7 @@ class DeleteQuery(Query):
|
|||||||
for related in cls._meta.get_all_related_many_to_many_objects():
|
for related in cls._meta.get_all_related_many_to_many_objects():
|
||||||
if not isinstance(related.field, generic.GenericRelation):
|
if not isinstance(related.field, generic.GenericRelation):
|
||||||
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
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(),
|
where.add((None, related.field.m2m_reverse_name(),
|
||||||
related.field, 'in',
|
related.field, 'in',
|
||||||
pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]),
|
pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]),
|
||||||
@ -1117,14 +1120,14 @@ class DeleteQuery(Query):
|
|||||||
self.do_query(related.field.m2m_db_table(), where)
|
self.do_query(related.field.m2m_db_table(), where)
|
||||||
|
|
||||||
for f in cls._meta.many_to_many:
|
for f in cls._meta.many_to_many:
|
||||||
w1 = WhereNode()
|
w1 = self.where_class()
|
||||||
if isinstance(f, generic.GenericRelation):
|
if isinstance(f, generic.GenericRelation):
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
field = f.rel.to._meta.get_field(f.content_type_field_name)
|
field = f.rel.to._meta.get_field(f.content_type_field_name)
|
||||||
w1.add((None, field.column, field, 'exact',
|
w1.add((None, field.column, field, 'exact',
|
||||||
ContentType.objects.get_for_model(cls).id), AND)
|
ContentType.objects.get_for_model(cls).id), AND)
|
||||||
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
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',
|
where.add((None, f.m2m_column_name(), f, 'in',
|
||||||
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
||||||
AND)
|
AND)
|
||||||
@ -1141,7 +1144,7 @@ class DeleteQuery(Query):
|
|||||||
lot of values in pk_list.
|
lot of values in pk_list.
|
||||||
"""
|
"""
|
||||||
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
||||||
where = WhereNode()
|
where = self.where_class()
|
||||||
field = self.model._meta.pk
|
field = self.model._meta.pk
|
||||||
where.add((None, field.column, field, 'in',
|
where.add((None, field.column, field, 'in',
|
||||||
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND)
|
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND)
|
||||||
@ -1185,7 +1188,7 @@ class UpdateQuery(Query):
|
|||||||
This is used by the QuerySet.delete_objects() method.
|
This is used by the QuerySet.delete_objects() method.
|
||||||
"""
|
"""
|
||||||
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
|
||||||
where = WhereNode()
|
where = self.where_class()
|
||||||
f = self.model._meta.pk
|
f = self.model._meta.pk
|
||||||
where.add((None, f.column, f, 'in',
|
where.add((None, f.column, f, 'in',
|
||||||
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user