mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Fixed #27849 -- Added filtering support to aggregates.
This commit is contained in:
parent
489421b015
commit
b78d100fa6
13 changed files with 290 additions and 55 deletions
|
@ -84,6 +84,16 @@ In a hurry? Here's how to do common aggregate queries, assuming the models above
|
|||
>>> pubs[0].num_books
|
||||
73
|
||||
|
||||
# Each publisher, with a separate count of books with a rating above and below 5
|
||||
>>> from django.db.models import Q
|
||||
>>> above_5 = Count('book', filter=Q(book__rating__gt=5))
|
||||
>>> below_5 = Count('book', filter=Q(book__rating__lte=5))
|
||||
>>> pubs = Publisher.objects.annotate(below_5=below_5).annotate(above_5=above_5)
|
||||
>>> pubs[0].above_5
|
||||
23
|
||||
>>> pubs[0].below_5
|
||||
12
|
||||
|
||||
# The top 5 publishers, in order by number of books.
|
||||
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
|
||||
>>> pubs[0].num_books
|
||||
|
@ -324,6 +334,8 @@ title that starts with "Django" using the query::
|
|||
|
||||
>>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price'))
|
||||
|
||||
.. _filtering-on-annotations:
|
||||
|
||||
Filtering on annotations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -339,6 +351,27 @@ you can issue the query::
|
|||
This query generates an annotated result set, and then generates a filter
|
||||
based upon that annotation.
|
||||
|
||||
If you need two annotations with two separate filters you can use the
|
||||
``filter`` argument with any aggregate. For example, to generate a list of
|
||||
authors with a count of highly rated books::
|
||||
|
||||
>>> highly_rated = Count('books', filter=Q(books__rating__gte=7))
|
||||
>>> Author.objects.annotate(num_books=Count('books'), highly_rated_books=highly_rated)
|
||||
|
||||
Each ``Author`` in the result set will have the ``num_books`` and
|
||||
``highly_rated_books`` attributes.
|
||||
|
||||
.. admonition:: Choosing between ``filter`` and ``QuerySet.filter()``
|
||||
|
||||
Avoid using the ``filter`` argument with a single annotation or
|
||||
aggregation. It's more efficient to use ``QuerySet.filter()`` to exclude
|
||||
rows. The aggregation ``filter`` argument is only useful when using two or
|
||||
more aggregations over the same relations with different conditionals.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
The ``filter`` argument was added to aggregates.
|
||||
|
||||
Order of ``annotate()`` and ``filter()`` clauses
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue