Author: mtredinnick
Date: 2008-02-22 19:35:34 -0600 (Fri, 22 Feb 2008)
New Revision: 7148

Modified:
   django/branches/queryset-refactor/django/db/models/manager.py
   django/branches/queryset-refactor/django/db/models/query.py
   django/branches/queryset-refactor/django/db/models/sql/query.py
   django/branches/queryset-refactor/docs/db-api.txt
   django/branches/queryset-refactor/tests/modeltests/ordering/models.py
   django/branches/queryset-refactor/tests/regressiontests/queries/models.py
Log:
queryset-refactor: Implemented the reverse() method on querysets.

Refs #5012.


Modified: django/branches/queryset-refactor/django/db/models/manager.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/manager.py       
2008-02-23 01:34:49 UTC (rev 7147)
+++ django/branches/queryset-refactor/django/db/models/manager.py       
2008-02-23 01:35:34 UTC (rev 7148)
@@ -104,6 +104,9 @@
     def update(self, *args, **kwargs):
         return self.get_query_set().update(*args, **kwargs)
 
+    def reverse(self, *args, **kwargs):
+        return self.get_query_set().reverse(*args, **kwargs)
+
     def _insert(self, *args, **kwargs):
         return self.get_query_set()._insert(*args, **kwargs)
 

Modified: django/branches/queryset-refactor/django/db/models/query.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/query.py 2008-02-23 
01:34:49 UTC (rev 7147)
+++ django/branches/queryset-refactor/django/db/models/query.py 2008-02-23 
01:35:34 UTC (rev 7148)
@@ -409,6 +409,14 @@
             clone.query.extra_order_by = order_by
         return clone
 
+    def reverse(self):
+        """
+        Reverses the ordering of the queryset.
+        """
+        clone = self._clone()
+        clone.query.standard_ordering = not clone.query.standard_ordering
+        return clone
+
     ###################
     # PRIVATE METHODS #
     ###################

Modified: django/branches/queryset-refactor/django/db/models/sql/query.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/sql/query.py     
2008-02-23 01:34:49 UTC (rev 7147)
+++ django/branches/queryset-refactor/django/db/models/sql/query.py     
2008-02-23 01:35:34 UTC (rev 7148)
@@ -92,6 +92,7 @@
         self.quote_cache = {}
         self.default_cols = True
         self.default_ordering = True
+        self.standard_ordering = True
 
         # SQL-related attributes
         self.select = []
@@ -160,6 +161,7 @@
         obj.quote_cache = {}
         obj.default_cols = self.default_cols
         obj.default_ordering = self.default_ordering
+        obj.standard_ordering = self.standard_ordering
         obj.select = self.select[:]
         obj.tables = self.tables[:]
         obj.where = copy.deepcopy(self.where)
@@ -487,23 +489,27 @@
         distinct = self.distinct
         select_aliases = self._select_aliases
         result = []
+        if self.standard_ordering:
+            asc, desc = ORDER_DIR['ASC']
+        else:
+            asc, desc = ORDER_DIR['DESC']
         for field in ordering:
             if field == '?':
                 result.append(self.connection.ops.random_function_sql())
                 continue
             if isinstance(field, int):
                 if field < 0:
-                    order = 'DESC'
+                    order = desc
                     field = -field
                 else:
-                    order = 'ASC'
+                    order = asc
                 result.append('%s %s' % (field, order))
                 continue
             if '.' in field:
                 # This came in through an extra(ordering=...) addition. Pass it
                 # on verbatim, after mapping the table name to an alias, if
                 # necessary.
-                col, order = get_order_dir(field)
+                col, order = get_order_dir(field, asc)
                 table, col = col.split('.', 1)
                 elt = '%s.%s' % (qn(self.table_alias(table)[0]), col)
                 if not distinct or elt in select_aliases:
@@ -512,12 +518,12 @@
                 # 'col' is of the form 'field' or 'field1__field2' or
                 # '-field1__field2__field', etc.
                 for table, col, order in self.find_ordering_name(field,
-                        self.model._meta):
+                        self.model._meta, default_order=asc):
                     elt = '%s.%s' % (qn(table), qn(col))
                     if not distinct or elt in select_aliases:
                         result.append('%s %s' % (elt, order))
             else:
-                col, order = get_order_dir(field)
+                col, order = get_order_dir(field, asc)
                 elt = qn(col)
                 if not distinct or elt in select_aliases:
                     result.append('%s %s' % (elt, order))

Modified: django/branches/queryset-refactor/docs/db-api.txt
===================================================================
--- django/branches/queryset-refactor/docs/db-api.txt   2008-02-23 01:34:49 UTC 
(rev 7147)
+++ django/branches/queryset-refactor/docs/db-api.txt   2008-02-23 01:35:34 UTC 
(rev 7148)
@@ -554,6 +554,26 @@
 respect to case-sensitivity, Django will order results however your database
 backend normally orders them.
 
+``reverse()``
+~~~~~~~~~~~~~
+
+**New in Django development version**
+
+If you want to reverse the order in which a queryset's elements are returned,
+you can use the ``reverse()`` method. Calling ``reverse()`` a second time
+restores the ordering back to the normal direction.
+
+To retrieve the ''last'' five items in a queryset, you could do this::
+
+    my_queryset.reverse()[:5]
+
+Note that this is not quite the same as slicing from the end of a sequence in
+Python. The above example will return the last item first, then the
+penultimate item and so on. If we had a Python sequence and looked at
+``seq[:-5]``, we would see the fifth-last item first. Django doesn't support
+that mode of access (slicing from the end), since it is not possible to do it
+efficiently in SQL.
+
 ``distinct()``
 ~~~~~~~~~~~~~~
 

Modified: django/branches/queryset-refactor/tests/modeltests/ordering/models.py
===================================================================
--- django/branches/queryset-refactor/tests/modeltests/ordering/models.py       
2008-02-23 01:34:49 UTC (rev 7147)
+++ django/branches/queryset-refactor/tests/modeltests/ordering/models.py       
2008-02-23 01:35:34 UTC (rev 7148)
@@ -48,6 +48,13 @@
 >>> Article.objects.order_by('pub_date', '-headline')
 [<Article: Article 1>, <Article: Article 3>, <Article: Article 2>, <Article: 
Article 4>]
 
+# Only the last order_by has any effect (since they each override any previous
+# ordering).
+>>> Article.objects.order_by('id')
+[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: 
Article 4>]
+>>> Article.objects.order_by('id').order_by('-headline')
+[<Article: Article 4>, <Article: Article 3>, <Article: Article 2>, <Article: 
Article 1>]
+
 # Use the 'stop' part of slicing notation to limit the results.
 >>> Article.objects.order_by('headline')[:2]
 [<Article: Article 1>, <Article: Article 2>]
@@ -65,10 +72,9 @@
 >>> Article.objects.order_by('?')
 [...]
 
-# order_by() overrides any previous ordering, so only the last one has any
-# effect.
->>> Article.objects.order_by('id')
-[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: 
Article 4>]
->>> Article.objects.order_by('id').order_by('-headline')
-[<Article: Article 4>, <Article: Article 3>, <Article: Article 2>, <Article: 
Article 1>]
+# Ordering can be reversed using the reverse() method on a queryset. This
+# allows you to extract things like "the last two items" (reverse and then
+# take the first two).
+>>> Article.objects.all().reverse()[:2]
+[<Article: Article 1>, <Article: Article 3>]
 """}

Modified: 
django/branches/queryset-refactor/tests/regressiontests/queries/models.py
===================================================================
--- django/branches/queryset-refactor/tests/regressiontests/queries/models.py   
2008-02-23 01:34:49 UTC (rev 7147)
+++ django/branches/queryset-refactor/tests/regressiontests/queries/models.py   
2008-02-23 01:35:34 UTC (rev 7148)
@@ -317,6 +317,8 @@
 [<Item: four>]
 >>> Item.objects.exclude(tags__name='t4').order_by('name').distinct()
 [<Item: one>, <Item: three>, <Item: two>]
+>>> Item.objects.exclude(tags__name='t4').order_by('name').distinct().reverse()
+[<Item: two>, <Item: three>, <Item: one>]
 >>> Author.objects.exclude(item__name='one').distinct().order_by('name')
 [<Author: a2>, <Author: a3>, <Author: a4>]
 


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to