Django

Code

Show
Ignore:
Timestamp:
06/25/07 07:47:19 (2 years ago)
Author:
mtredinnick
Message:

unicode: Merged from trunk up to [5530]. Oracle backend has not been ported to
support unicode yet.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/unicode

    • Property svnmerge-integrated changed from /django/trunk:1-5460 to /django/trunk:1-5530
  • django/branches/unicode/django/db/models/query.py

    r5399 r5531  
    66from django.utils.encoding import smart_unicode 
    77from django.contrib.contenttypes import generic 
     8import datetime 
    89import operator 
    910import re 
    1011 
    11 # For Python 2.3 
    12 if not hasattr(__builtins__, 'set'): 
    13     from sets import Set as set 
     12try: 
     13    set 
     14except NameError: 
     15    from sets import Set as set   # Python 2.3 fallback 
    1416 
    1517# The string constant used to separate query parts 
     
    7981        return backend.quote_name(word) 
    8082 
    81 class QuerySet(object): 
     83class _QuerySet(object): 
    8284    "Represents a lazy database lookup for a set of objects" 
    8385    def __init__(self, model=None): 
     
    183185        cursor = connection.cursor() 
    184186        cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 
     187 
    185188        fill_cache = self._select_related 
    186         index_end = len(self.model._meta.fields) 
     189        fields = self.model._meta.fields 
     190        index_end = len(fields) 
     191        has_resolve_columns = hasattr(self, 'resolve_columns') 
    187192        while 1: 
    188193            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     
    190195                raise StopIteration 
    191196            for row in rows: 
     197                if has_resolve_columns: 
     198                    row = self.resolve_columns(row, fields) 
    192199                if fill_cache: 
    193200                    obj, index_end = get_cached_row(klass=self.model, row=row, 
     
    553560        return select, " ".join(sql), params 
    554561 
     562# Use the backend's QuerySet class if it defines one, otherwise use _QuerySet. 
     563if hasattr(backend, 'get_query_set_class'): 
     564    QuerySet = backend.get_query_set_class(_QuerySet) 
     565else: 
     566    QuerySet = _QuerySet 
     567 
    555568class ValuesQuerySet(QuerySet): 
    556569    def __init__(self, *args, **kwargs): 
     
    567580        # self._fields is a list of field names to fetch. 
    568581        if self._fields: 
    569             #columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 
    570582            if not self._select: 
    571                 columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 
     583                fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] 
    572584            else: 
    573                 columns = [] 
     585                fields = [] 
    574586                for f in self._fields: 
    575587                    if f in [field.name for field in self.model._meta.fields]: 
    576                         columns.append( self.model._meta.get_field(f, many_to_many=False).column
     588                        fields.append(self.model._meta.get_field(f, many_to_many=False)
    577589                    elif not self._select.has_key( f ): 
    578590                        raise FieldDoesNotExist, '%s has no field named %r' % ( self.model._meta.object_name, f ) 
     
    580592            field_names = self._fields 
    581593        else: # Default to all fields. 
    582             columns = [f.column for f in self.model._meta.fields] 
    583             field_names = [f.attname for f in self.model._meta.fields] 
    584  
     594            fields = self.model._meta.fields 
     595            field_names = [f.attname for f in fields] 
     596 
     597        columns = [f.column for f in fields] 
    585598        select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] 
    586  
    587599        # Add any additional SELECTs. 
    588600        if self._select: 
     
    591603        cursor = connection.cursor() 
    592604        cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 
     605 
     606        has_resolve_columns = hasattr(self, 'resolve_columns') 
    593607        while 1: 
    594608            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     
    596610                raise StopIteration 
    597611            for row in rows: 
     612                if has_resolve_columns: 
     613                    row = self.resolve_columns(row, fields) 
    598614                yield dict(zip(field_names, row)) 
    599615 
     
    606622    def iterator(self): 
    607623        from django.db.backends.util import typecast_timestamp 
     624        from django.db.models.fields import DateTimeField 
    608625        self._order_by = () # Clear this because it'll mess things up otherwise. 
    609626        if self._field.null: 
    610627            self._where.append('%s.%s IS NOT NULL' % \ 
    611628                (backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column))) 
    612  
    613629        try: 
    614630            select, sql, params = self._get_sql_clause() 
     
    616632            raise StopIteration 
    617633 
    618         sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1 %s' % \ 
     634        table_name = backend.quote_name(self.model._meta.db_table) 
     635        field_name = backend.quote_name(self._field.column) 
     636 
     637        if backend.allows_group_by_ordinal: 
     638            group_by = '1' 
     639        else: 
     640            group_by = backend.get_date_trunc_sql(self._kind, 
     641                                                  '%s.%s' % (table_name, field_name)) 
     642 
     643        sql = 'SELECT %s %s GROUP BY %s ORDER BY 1 %s' % \ 
    619644            (backend.get_date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table), 
    620             backend.quote_name(self._field.column))), sql, self._order) 
     645            backend.quote_name(self._field.column))), sql, group_by, self._order) 
    621646        cursor = connection.cursor() 
    622647        cursor.execute(sql, params) 
    623         # We have to manually run typecast_timestamp(str()) on the results, because 
    624         # MySQL doesn't automatically cast the result of date functions as datetime 
    625         # objects -- MySQL returns the values as strings, instead. 
    626         return [typecast_timestamp(str(row[0])) for row in cursor.fetchall()] 
     648 
     649        has_resolve_columns = hasattr(self, 'resolve_columns') 
     650        needs_datetime_string_cast = backend.needs_datetime_string_cast 
     651        dates = [] 
     652        # It would be better to use self._field here instead of DateTimeField(), 
     653        # but in Oracle that will result in a list of datetime.date instead of 
     654        # datetime.datetime. 
     655        fields = [DateTimeField()] 
     656        while 1: 
     657            rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 
     658            if not rows: 
     659                return dates 
     660            for row in rows: 
     661                date = row[0] 
     662                if has_resolve_columns: 
     663                    date = self.resolve_columns([date], fields)[0] 
     664                elif needs_datetime_string_cast: 
     665                    date = typecast_timestamp(str(date)) 
     666                dates.append(date) 
    627667 
    628668    def _clone(self, klass=None, **kwargs): 
     
    732772        table_prefix = backend.quote_name(table_prefix[:-1])+'.' 
    733773    field_name = backend.quote_name(field_name) 
     774    if type(value) == datetime.datetime and backend.get_datetime_cast_sql(): 
     775        cast_sql = backend.get_datetime_cast_sql() 
     776    else: 
     777        cast_sql = '%s' 
     778    if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops: 
     779        format = 'UPPER(%s%s) %s' 
     780    else: 
     781        format = '%s%s %s' 
    734782    try: 
    735         return '%s%s %s' % (table_prefix, field_name, (backend.OPERATOR_MAPPING[lookup_type] % '%s')) 
     783        return format % (table_prefix, field_name, 
     784                         backend.OPERATOR_MAPPING[lookup_type] % cast_sql) 
    736785    except KeyError: 
    737786        pass