Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

queryset-refactor: Added the ability to use a subclass of WhereNode i…

…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...
commit e016a4f987efc6c43ea6c80540456cdd161b2434 1 parent dd2251a
Malcolm Tredinnick authored January 27, 2008

Showing 1 changed file with 14 additions and 11 deletions. Show diff stats Hide diff stats

  1. 25  django/db/models/sql/query.py
25  django/db/models/sql/query.py
@@ -77,8 +77,9 @@ class Query(object):
77 77
     LOUTER = 'LEFT OUTER JOIN'
78 78
 
79 79
     alias_prefix = 'T'
  80
+    query_terms = QUERY_TERMS
80 81
 
81  
-    def __init__(self, model, connection):
  82
+    def __init__(self, model, connection, where=WhereNode):
82 83
         self.model = model
83 84
         self.connection = connection
84 85
         self.alias_map = {}     # Maps alias to table name
@@ -91,7 +92,8 @@ def __init__(self, model, connection):
91 92
         # SQL-related attributes
92 93
         self.select = []
93 94
         self.tables = []    # Aliases in the order they are created.
94  
-        self.where = WhereNode()
  95
+        self.where = where()
  96
+        self.where_class = where
95 97
         self.group_by = []
96 98
         self.having = []
97 99
         self.order_by = []
@@ -156,6 +158,7 @@ def clone(self, klass=None, **kwargs):
156 158
         obj.select = self.select[:]
157 159
         obj.tables = self.tables[:]
158 160
         obj.where = copy.deepcopy(self.where)
  161
+        obj.where_class = self.where_class
159 162
         obj.group_by = self.group_by[:]
160 163
         obj.having = self.having[:]
161 164
         obj.order_by = self.order_by[:]
@@ -192,7 +195,7 @@ def get_count(self):
192 195
         obj.clear_limits()
193 196
         obj.select_related = False
194 197
         if obj.distinct and len(obj.select) > 1:
195  
-            obj = self.clone(CountQuery, _query=obj, where=WhereNode(),
  198
+            obj = self.clone(CountQuery, _query=obj, where=self.where_class(),
196 199
                     distinct=False)
197 200
             obj.select = []
198 201
             obj.extra_select = SortedDict()
@@ -319,12 +322,12 @@ def combine(self, rhs, connector):
319 322
         elif self.where:
320 323
             # rhs has an empty where clause. Make it match everything (see
321 324
             # above for reasoning).
322  
-            w = WhereNode()
  325
+            w = self.where_class()
323 326
             alias = self.join((None, self.model._meta.db_table, None, None))
324 327
             pk = self.model._meta.pk
325 328
             w.add(EverythingNode(), AND)
326 329
         else:
327  
-            w = WhereNode()
  330
+            w = self.where_class()
328 331
         self.where.add(w, connector)
329 332
 
330 333
         # Selection columns and extra extensions are those provided by 'rhs'.
@@ -704,7 +707,7 @@ def add_filter(self, filter_expr, connector=AND, negate=False):
704 707
             raise TypeError("Cannot parse keyword query %r" % arg)
705 708
 
706 709
         # Work out the lookup type and remove it from 'parts', if necessary.
707  
-        if len(parts) == 1 or parts[-1] not in QUERY_TERMS:
  710
+        if len(parts) == 1 or parts[-1] not in self.query_terms:
708 711
             lookup_type = 'exact'
709 712
         else:
710 713
             lookup_type = parts.pop()
@@ -1109,7 +1112,7 @@ def delete_batch_related(self, pk_list):
1109 1112
         for related in cls._meta.get_all_related_many_to_many_objects():
1110 1113
             if not isinstance(related.field, generic.GenericRelation):
1111 1114
                 for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
1112  
-                    where = WhereNode()
  1115
+                    where = self.where_class()
1113 1116
                     where.add((None, related.field.m2m_reverse_name(),
1114 1117
                             related.field, 'in',
1115 1118
                             pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]),
@@ -1117,14 +1120,14 @@ def delete_batch_related(self, pk_list):
1117 1120
                     self.do_query(related.field.m2m_db_table(), where)
1118 1121
 
1119 1122
         for f in cls._meta.many_to_many:
1120  
-            w1 = WhereNode()
  1123
+            w1 = self.where_class()
1121 1124
             if isinstance(f, generic.GenericRelation):
1122 1125
                 from django.contrib.contenttypes.models import ContentType
1123 1126
                 field = f.rel.to._meta.get_field(f.content_type_field_name)
1124 1127
                 w1.add((None, field.column, field, 'exact',
1125 1128
                         ContentType.objects.get_for_model(cls).id), AND)
1126 1129
             for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
1127  
-                where = WhereNode()
  1130
+                where = self.where_class()
1128 1131
                 where.add((None, f.m2m_column_name(), f, 'in',
1129 1132
                         pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),
1130 1133
                         AND)
@@ -1141,7 +1144,7 @@ def delete_batch(self, pk_list):
1141 1144
         lot of values in pk_list.
1142 1145
         """
1143 1146
         for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
1144  
-            where = WhereNode()
  1147
+            where = self.where_class()
1145 1148
             field = self.model._meta.pk
1146 1149
             where.add((None, field.column, field, 'in',
1147 1150
                     pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND)
@@ -1185,7 +1188,7 @@ def clear_related(self, related_field, pk_list):
1185 1188
         This is used by the QuerySet.delete_objects() method.
1186 1189
         """
1187 1190
         for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
1188  
-            where = WhereNode()
  1191
+            where = self.where_class()
1189 1192
             f = self.model._meta.pk
1190 1193
             where.add((None, f.column, f, 'in',
1191 1194
                     pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),

0 notes on commit e016a4f

Please sign in to comment.
Something went wrong with that request. Please try again.