Django

Code

Changeset 7148

Show
Ignore:
Timestamp:
02/22/08 19:35:34 (4 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Implemented the reverse() method on querysets.

Refs #5012.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/manager.py

    r7146 r7148  
    105105        return self.get_query_set().update(*args, **kwargs) 
    106106 
     107    def reverse(self, *args, **kwargs): 
     108        return self.get_query_set().reverse(*args, **kwargs) 
     109 
    107110    def _insert(self, *args, **kwargs): 
    108111        return self.get_query_set()._insert(*args, **kwargs) 
  • django/branches/queryset-refactor/django/db/models/query.py

    r7094 r7148  
    408408        if order_by: 
    409409            clone.query.extra_order_by = order_by 
     410        return clone 
     411 
     412    def reverse(self): 
     413        """ 
     414        Reverses the ordering of the queryset. 
     415        """ 
     416        clone = self._clone() 
     417        clone.query.standard_ordering = not clone.query.standard_ordering 
    410418        return clone 
    411419 
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r7147 r7148  
    9393        self.default_cols = True 
    9494        self.default_ordering = True 
     95        self.standard_ordering = True 
    9596 
    9697        # SQL-related attributes 
     
    161162        obj.default_cols = self.default_cols 
    162163        obj.default_ordering = self.default_ordering 
     164        obj.standard_ordering = self.standard_ordering 
    163165        obj.select = self.select[:] 
    164166        obj.tables = self.tables[:] 
     
    488490        select_aliases = self._select_aliases 
    489491        result = [] 
     492        if self.standard_ordering: 
     493            asc, desc = ORDER_DIR['ASC'] 
     494        else: 
     495            asc, desc = ORDER_DIR['DESC'] 
    490496        for field in ordering: 
    491497            if field == '?': 
     
    494500            if isinstance(field, int): 
    495501                if field < 0: 
    496                     order = 'DESC' 
     502                    order = desc 
    497503                    field = -field 
    498504                else: 
    499                     order = 'ASC' 
     505                    order = asc 
    500506                result.append('%s %s' % (field, order)) 
    501507                continue 
     
    504510                # on verbatim, after mapping the table name to an alias, if 
    505511                # necessary. 
    506                 col, order = get_order_dir(field
     512                col, order = get_order_dir(field, asc
    507513                table, col = col.split('.', 1) 
    508514                elt = '%s.%s' % (qn(self.table_alias(table)[0]), col) 
     
    513519                # '-field1__field2__field', etc. 
    514520                for table, col, order in self.find_ordering_name(field, 
    515                         self.model._meta): 
     521                        self.model._meta, default_order=asc): 
    516522                    elt = '%s.%s' % (qn(table), qn(col)) 
    517523                    if not distinct or elt in select_aliases: 
    518524                        result.append('%s %s' % (elt, order)) 
    519525            else: 
    520                 col, order = get_order_dir(field
     526                col, order = get_order_dir(field, asc
    521527                elt = qn(col) 
    522528                if not distinct or elt in select_aliases: 
  • django/branches/queryset-refactor/docs/db-api.txt

    r7147 r7148  
    554554respect to case-sensitivity, Django will order results however your database 
    555555backend normally orders them. 
     556 
     557``reverse()`` 
     558~~~~~~~~~~~~~ 
     559 
     560**New in Django development version** 
     561 
     562If you want to reverse the order in which a queryset's elements are returned, 
     563you can use the ``reverse()`` method. Calling ``reverse()`` a second time 
     564restores the ordering back to the normal direction. 
     565 
     566To retrieve the ''last'' five items in a queryset, you could do this:: 
     567 
     568    my_queryset.reverse()[:5] 
     569 
     570Note that this is not quite the same as slicing from the end of a sequence in 
     571Python. The above example will return the last item first, then the 
     572penultimate item and so on. If we had a Python sequence and looked at 
     573``seq[:-5]``, we would see the fifth-last item first. Django doesn't support 
     574that mode of access (slicing from the end), since it is not possible to do it 
     575efficiently in SQL. 
    556576 
    557577``distinct()`` 
  • django/branches/queryset-refactor/tests/modeltests/ordering/models.py

    r7124 r7148  
    4949[<Article: Article 1>, <Article: Article 3>, <Article: Article 2>, <Article: Article 4>] 
    5050 
     51# Only the last order_by has any effect (since they each override any previous 
     52# ordering). 
     53>>> Article.objects.order_by('id') 
     54[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>] 
     55>>> Article.objects.order_by('id').order_by('-headline') 
     56[<Article: Article 4>, <Article: Article 3>, <Article: Article 2>, <Article: Article 1>] 
     57 
    5158# Use the 'stop' part of slicing notation to limit the results. 
    5259>>> Article.objects.order_by('headline')[:2] 
     
    6673[...] 
    6774 
    68 # order_by() overrides any previous ordering, so only the last one has any 
    69 # effect. 
    70 >>> Article.objects.order_by('id') 
    71 [<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>] 
    72 >>> Article.objects.order_by('id').order_by('-headline') 
    73 [<Article: Article 4>, <Article: Article 3>, <Article: Article 2>, <Article: Article 1>] 
     75# Ordering can be reversed using the reverse() method on a queryset. This 
     76# allows you to extract things like "the last two items" (reverse and then 
     77# take the first two). 
     78>>> Article.objects.all().reverse()[:2] 
     79[<Article: Article 1>, <Article: Article 3>] 
    7480"""} 
  • django/branches/queryset-refactor/tests/regressiontests/queries/models.py

    r7046 r7148  
    318318>>> Item.objects.exclude(tags__name='t4').order_by('name').distinct() 
    319319[<Item: one>, <Item: three>, <Item: two>] 
     320>>> Item.objects.exclude(tags__name='t4').order_by('name').distinct().reverse() 
     321[<Item: two>, <Item: three>, <Item: one>] 
    320322>>> Author.objects.exclude(item__name='one').distinct().order_by('name') 
    321323[<Author: a2>, <Author: a3>, <Author: a4>]