Index: branches/queryset-refactor/django/db/models/sql/query.py
===================================================================
--- branches/queryset-refactor/django/db/models/sql/query.py	(revision 6965)
+++ branches/queryset-refactor/django/db/models/sql/query.py	(working copy)
@@ -78,7 +78,7 @@
 
     alias_prefix = 'T'
 
-    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
@@ -91,7 +91,8 @@
         # 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 = []
@@ -156,6 +157,7 @@
         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[:]
@@ -192,7 +194,7 @@
         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()
@@ -210,6 +212,12 @@
 
         return number
 
+    def get_terms(self):
+        """
+        Returns all valid Query lookup types.
+        """
+        return QUERY_TERMS
+
     def as_sql(self, with_limits=True):
         """
         Creates the SQL for this query. Returns the SQL string and list of
@@ -320,12 +328,12 @@
         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([alias, pk.column, pk, 'isnull', False], AND)
         else:
-            w = WhereNode()
+            w = self.where_class()
         self.where.add(w, connector)
 
         # Selection columns and extra extensions are those provided by 'rhs'.
@@ -705,7 +713,7 @@
             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.get_terms():
             lookup_type = 'exact'
         else:
             lookup_type = parts.pop()
@@ -1110,7 +1118,7 @@
         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]),
@@ -1118,14 +1126,14 @@
                     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)
@@ -1142,7 +1150,7 @@
         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)
@@ -1186,7 +1194,7 @@
         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]),
