Django

Code

Ticket #6261: query_wherenode.diff

File query_wherenode.diff, 5.0 kB (added by jbronn, 1 year ago)

Patch adding customization options to the Query class.

  • branches/queryset-refactor/django/db/models/sql/query.py

    old new  
    7878 
    7979    alias_prefix = 'T' 
    8080 
    81     def __init__(self, model, connection): 
     81    def __init__(self, model, connection, where=WhereNode): 
    8282        self.model = model 
    8383        self.connection = connection 
    8484        self.alias_map = {}     # Maps alias to table name 
     
    9191        # SQL-related attributes 
    9292        self.select = [] 
    9393        self.tables = []    # Aliases in the order they are created. 
    94         self.where = WhereNode() 
     94        self.where = where() 
     95        self.where_class = where 
    9596        self.group_by = [] 
    9697        self.having = [] 
    9798        self.order_by = [] 
     
    156157        obj.select = self.select[:] 
    157158        obj.tables = self.tables[:] 
    158159        obj.where = copy.deepcopy(self.where) 
     160        obj.where_class = self.where_class 
    159161        obj.group_by = self.group_by[:] 
    160162        obj.having = self.having[:] 
    161163        obj.order_by = self.order_by[:] 
     
    192194        obj.clear_limits() 
    193195        obj.select_related = False 
    194196        if obj.distinct and len(obj.select) > 1: 
    195             obj = self.clone(CountQuery, _query=obj, where=WhereNode(), 
     197            obj = self.clone(CountQuery, _query=obj, where=self.where_class(), 
    196198                    distinct=False) 
    197199            obj.select = [] 
    198200            obj.extra_select = SortedDict() 
     
    210212 
    211213        return number 
    212214 
     215    def get_terms(self): 
     216        """ 
     217        Returns all valid Query lookup types. 
     218        """ 
     219        return QUERY_TERMS 
     220 
    213221    def as_sql(self, with_limits=True): 
    214222        """ 
    215223        Creates the SQL for this query. Returns the SQL string and list of 
     
    320328        elif self.where: 
    321329            # rhs has an empty where clause. Make it match everything (see 
    322330            # above for reasoning). 
    323             w = WhereNode() 
     331            w = self.where_class() 
    324332            alias = self.join((None, self.model._meta.db_table, None, None)) 
    325333            pk = self.model._meta.pk 
    326334            w.add([alias, pk.column, pk, 'isnull', False], AND) 
    327335        else: 
    328             w = WhereNode() 
     336            w = self.where_class() 
    329337        self.where.add(w, connector) 
    330338 
    331339        # Selection columns and extra extensions are those provided by 'rhs'. 
     
    705713            raise TypeError("Cannot parse keyword query %r" % arg) 
    706714 
    707715        # Work out the lookup type and remove it from 'parts', if necessary. 
    708         if len(parts) == 1 or parts[-1] not in QUERY_TERMS
     716        if len(parts) == 1 or parts[-1] not in self.get_terms()
    709717            lookup_type = 'exact' 
    710718        else: 
    711719            lookup_type = parts.pop() 
     
    11101118        for related in cls._meta.get_all_related_many_to_many_objects(): 
    11111119            if not isinstance(related.field, generic.GenericRelation): 
    11121120                for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 
    1113                     where = WhereNode() 
     1121                    where = self.where_class() 
    11141122                    where.add((None, related.field.m2m_reverse_name(), 
    11151123                            related.field, 'in', 
    11161124                            pk_list[offset : offset+GET_ITERATOR_CHUNK_SIZE]), 
     
    11181126                    self.do_query(related.field.m2m_db_table(), where) 
    11191127 
    11201128        for f in cls._meta.many_to_many: 
    1121             w1 = WhereNode() 
     1129            w1 = self.where_class() 
    11221130            if isinstance(f, generic.GenericRelation): 
    11231131                from django.contrib.contenttypes.models import ContentType 
    11241132                field = f.rel.to._meta.get_field(f.content_type_field_name) 
    11251133                w1.add((None, field.column, field, 'exact', 
    11261134                        ContentType.objects.get_for_model(cls).id), AND) 
    11271135            for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 
    1128                 where = WhereNode() 
     1136                where = self.where_class() 
    11291137                where.add((None, f.m2m_column_name(), f, 'in', 
    11301138                        pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), 
    11311139                        AND) 
     
    11421150        lot of values in pk_list. 
    11431151        """ 
    11441152        for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 
    1145             where = WhereNode() 
     1153            where = self.where_class() 
    11461154            field = self.model._meta.pk 
    11471155            where.add((None, field.column, field, 'in', 
    11481156                    pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND) 
     
    11861194        This is used by the QuerySet.delete_objects() method. 
    11871195        """ 
    11881196        for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): 
    1189             where = WhereNode() 
     1197            where = self.where_class() 
    11901198            f = self.model._meta.pk 
    11911199            where.add((None, f.column, f, 'in', 
    11921200                    pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]),