Author: mtredinnick
Date: 2009-03-25 04:05:38 -0500 (Wed, 25 Mar 2009)
New Revision: 10172

Modified:
   django/trunk/docs/ref/models/querysets.txt
   django/trunk/docs/topics/db/aggregation.txt
Log:
Fixed #10574 -- Documented interaction between annotations and order_by.

In the future, I'd like to fix this properly, but the current behavior
has the advantage of being consistent across the board (and changing it
everywhere is backwards-incompatible with documented functionality).

Modified: django/trunk/docs/ref/models/querysets.txt
===================================================================
--- django/trunk/docs/ref/models/querysets.txt  2009-03-25 08:28:57 UTC (rev 
10171)
+++ django/trunk/docs/ref/models/querysets.txt  2009-03-25 09:05:38 UTC (rev 
10172)
@@ -296,6 +296,8 @@
 ordering was undefined prior to calling ``reverse()``, and will remain
 undefined afterward).
 
+.. _querysets-distinct:
+
 ``distinct()``
 ~~~~~~~~~~~~~~
 

Modified: django/trunk/docs/topics/db/aggregation.txt
===================================================================
--- django/trunk/docs/topics/db/aggregation.txt 2009-03-25 08:28:57 UTC (rev 
10171)
+++ django/trunk/docs/topics/db/aggregation.txt 2009-03-25 09:05:38 UTC (rev 
10172)
@@ -315,6 +315,57 @@
 clause is applied after the ``annotate()`` clause, you need to explicitly
 include the aggregate column.
 
+Interaction with default ordering or ``order_by()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fields that are mentioned in the ``order_by()`` part of a queryset (or which
+are used in the default ordering on a model) are used when selecting the
+output data, even if they are not otherwise specified in the ``values()``
+call. These extra fields are used to group "like" results together and they
+can make otherwise identical result rows appear to be separate. This shows up,
+particularly, when counting things.
+
+By way of example, suppose you have a model like this::
+
+    class Item(models.Model):
+        name = models.CharField(max_length=10)
+        data = models.IntegerField()
+
+        class Meta:
+            ordering = ["name"]
+
+The important part here is the default ordering on the ``name`` field. If you
+want to count how many times each distinct ``data`` value appears, you might
+try this::
+
+    # Warning: not quite correct!
+    Item.objects.values("data").annotate(Count("id"))
+
+...which will group the ``Item`` objects by their common ``data`` values and
+then count the number of ``id`` values in each group. Except that it won't
+quite work. The default ordering by ``name`` will also play a part in the
+grouping, so this query will group by distinct ``(data, name)`` pairs, which
+isn't what you want. Instead, you should construct this queryset::
+
+    Item.objects.values("data").annotate(Count("id")).order_by()
+
+...clearing any ordering in the query. You could also order by, say, ``data``
+without any harmful effects, since that is already playing a role in the
+query.
+
+This behavior is the same as that noted in the queryset documentation for
+:ref:`distinct() <querysets-distinct>` and the general rule is the same:
+normally you won't want extra columns playing a part in the result, so clear
+out the ordering, or at least make sure it's restricted only to those fields
+you also select in a ``values()`` call.
+
+.. note::
+    You might reasonably ask why Django doesn't remove the extraneous columns
+    for you. The main reason is consistency with ``distinct()`` and other
+    places: Django **never** removes ordering constraints that you have
+    specified (and we can't change those other methods' behavior, as that
+    would violate our :ref:`misc-api-stability` policy).
+
 Aggregating annotations
 -----------------------
 


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

Reply via email to