Fixed #24060 -- Added OrderBy Expressions

This commit is contained in:
Josh Smeaton 2015-01-10 02:16:16 +11:00
parent f48e2258a9
commit 21b858cb67
9 changed files with 310 additions and 54 deletions

View file

@ -5,7 +5,7 @@ Query Expressions
.. currentmodule:: django.db.models
Query expressions describe a value or a computation that can be used as part of
a filter, an annotation, or an aggregation. There are a number of built-in
a filter, order by, annotation, or aggregate. There are a number of built-in
expressions (documented below) that can be used to help you write queries.
Expressions can be combined, or in some cases nested, to form more complex
computations.
@ -58,6 +58,10 @@ Some examples
# Aggregates can contain complex computations also
Company.objects.annotate(num_offerings=Count(F('products') + F('services')))
# Expressions can also be used in order_by()
Company.objects.order_by(Length('name').asc())
Company.objects.order_by(Length('name').desc())
Built-in Expressions
====================
@ -428,6 +432,24 @@ calling the appropriate methods on the wrapped expression.
nested expressions. ``F()`` objects, in particular, hold a reference
to a column.
.. method:: asc()
Returns the expression ready to be sorted in ascending order.
.. method:: desc()
Returns the expression ready to be sorted in descending order.
.. method:: reverse_ordering()
Returns ``self`` with any modifications required to reverse the sort
order within an ``order_by`` call. As an example, an expression
implementing ``NULLS LAST`` would change its value to be
``NULLS FIRST``. Modifications are only required for expressions that
implement sort order like ``OrderBy``. This method is called when
:meth:`~django.db.models.query.QuerySet.reverse()` is called on a
queryset.
Writing your own Query Expressions
----------------------------------

View file

@ -322,17 +322,28 @@ identical to::
Entry.objects.order_by('blog__name')
It is also possible to order a queryset by a related field, without incurring
the cost of a JOIN, by referring to the ``_id`` of the related field::
# No Join
Entry.objects.order_by('blog_id')
# Join
Entry.objects.order_by('blog__id')
.. versionadded:: 1.7
Note that it is also possible to order a queryset by a related field,
without incurring the cost of a JOIN, by referring to the ``_id`` of the
related field::
The ability to order a queryset by a related field, without incurring
the cost of a JOIN was added.
# No Join
Entry.objects.order_by('blog_id')
You can also order by :doc:`query expressions </ref/models/expressions>` by
calling ``asc()`` or ``desc()`` on the expression::
# Join
Entry.objects.order_by('blog__id')
Entry.objects.order_by(Coalesce('summary', 'headline').desc())
.. versionadded:: 1.8
Ordering by query expressions was added.
Be cautious when ordering by fields in related models if you are also using
:meth:`distinct()`. See the note in :meth:`distinct` for an explanation of how
@ -367,6 +378,16 @@ There's no way to specify whether ordering should be case sensitive. With
respect to case-sensitivity, Django will order results however your database
backend normally orders them.
You can order by a field converted to lowercase with
:class:`~django.db.models.functions.Lower` which will achieve case-consistent
ordering::
Entry.objects.order_by(Lower('headline').desc())
.. versionadded:: 1.8
The ability to order by expressions like ``Lower`` was added.
If you don't want any ordering to be applied to a query, not even the default
ordering, call :meth:`order_by()` with no parameters.