Django

Code

Changeset 4505

Show
Ignore:
Timestamp:
02/14/07 00:32:32 (2 years ago)
Author:
adrian
Message:

Changed year lookup to use a BETWEEN SQL statement instead of comparing the result of EXTRACT(year). This should be more efficient.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/models/fields/__init__.py

    r4486 r4505  
    165165    def get_db_prep_lookup(self, lookup_type, value): 
    166166        "Returns field's value prepared for database lookup." 
    167         if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'year', 'month', 'day', 'search'): 
     167        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'): 
    168168            return [value] 
    169169        elif lookup_type in ('range', 'in'): 
     
    179179        elif lookup_type == 'isnull': 
    180180            return [] 
    181         raise TypeError, "Field has invalid lookup: %s" % lookup_type 
     181        elif lookup_type == 'year': 
     182            try: 
     183                value = int(value) 
     184            except ValueError: 
     185                raise ValueError("The __year lookup type requires an integer argument") 
     186            return ['%s-01-01 00:00:00' % value, '%s-12-31 23:59:59.999999' % value] 
     187        raise TypeError("Field has invalid lookup: %s" % lookup_type) 
    182188 
    183189    def has_default(self): 
  • django/trunk/django/db/models/query.py

    r4488 r4505  
    199199        counter._order_by = () 
    200200        counter._select_related = False 
    201          
     201 
    202202        offset = counter._offset 
    203203        limit = counter._limit 
    204204        counter._offset = None 
    205205        counter._limit = None 
    206          
     206 
    207207        try: 
    208208            select, sql, params = counter._get_sql_clause() 
    209209        except EmptyResultSet: 
    210210            return 0 
    211              
     211 
    212212        cursor = connection.cursor() 
    213213        if self._distinct: 
     
    554554            columns = [f.column for f in self.model._meta.fields] 
    555555            field_names = [f.attname for f in self.model._meta.fields] 
    556          
     556 
    557557        select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] 
    558558        cursor = connection.cursor() 
     
    577577            self._where.append('%s.%s IS NOT NULL' % \ 
    578578                (backend.quote_name(self.model._meta.db_table), backend.quote_name(self._field.column))) 
    579                  
     579 
    580580        try: 
    581581            select, sql, params = self._get_sql_clause() 
    582582        except EmptyResultSet: 
    583583            raise StopIteration 
    584          
     584 
    585585        sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1 %s' % \ 
    586586            (backend.get_date_trunc_sql(self._kind, '%s.%s' % (backend.quote_name(self.model._meta.db_table), 
     
    599599        c._order = self._order 
    600600        return c 
    601      
     601 
    602602class EmptyQuerySet(QuerySet): 
    603603    def __init__(self, model=None): 
    604604        super(EmptyQuerySet, self).__init__(model) 
    605605        self._result_cache = [] 
    606          
     606 
    607607    def count(self): 
    608608        return 0 
    609          
     609 
    610610    def delete(self): 
    611611        pass 
     
    709709        else: 
    710710            raise EmptyResultSet 
    711     elif lookup_type == 'range'
     711    elif lookup_type in ('range', 'year')
    712712        return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) 
    713     elif lookup_type in ('year', 'month', 'day'): 
     713    elif lookup_type in ('month', 'day'): 
    714714        return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name) 
    715715    elif lookup_type == 'isnull': 
     
    792792        if len(path) < 1: 
    793793            raise TypeError, "Cannot parse keyword query %r" % kwarg 
    794          
     794 
    795795        if value is None: 
    796796            # Interpret '__exact=None' as the sql '= NULL'; otherwise, reject 
     
    10081008        for f in cls._meta.many_to_many: 
    10091009            if isinstance(f, GenericRelation): 
    1010                 from django.contrib.contenttypes.models import ContentType  
     1010                from django.contrib.contenttypes.models import ContentType 
    10111011                query_extra = 'AND %s=%%s' % f.rel.to._meta.get_field(f.content_type_field_name).column 
    10121012                args_extra = [ContentType.objects.get_for_model(cls).id] 
  • django/trunk/tests/modeltests/basic/models.py

    r4228 r4505  
    1313    class Meta: 
    1414        ordering = ('pub_date','headline') 
    15          
     15 
    1616    def __str__(self): 
    1717        return self.headline 
     
    320320>>> Article.objects.all() 
    321321[<Article: Article 6>, <Article: Default headline>, <Article: Article 7>, <Article: Updated article 8>] 
    322  
    323322"""} 
    324323 
     
    359358>>> Article.objects.get(headline="Article 10") 
    360359<Article: Article 10> 
    361 """ 
     360 
     361# Edge-case test: A year lookup should retrieve all objects in the given 
     362year, including Jan. 1 and Dec. 31. 
     363>>> a11 = Article.objects.create(headline='Article 11', pub_date=datetime(2008, 1, 1)) 
     364>>> a12 = Article.objects.create(headline='Article 12', pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999)) 
     365>>> Article.objects.filter(pub_date__year=2008) 
     366[<Article: Article 11>, <Article: Article 12>] 
     367"""