tags:

views:

22

answers:

1

The Django documentation gives examples for using annotate() to produce aggregate results based on related fields of a QuerySet (i.e., using joins in annotate()).

A simplified example from the docs is for instance Store.objects.annotate(min_price=Min('books__price')), where books is a ManyToMany field of Store to Book and price is a field of Book.

To continue this example, how would I generate an annotated QuerySet of Store objects with the lowest prices not for all books in the store, but just for books with "author='William Shakespeare'"? In other words, how do I filter the related fields used to calculate the aggregate?

A: 

The documentation explains how to do this:

Store.objects.filter(books__author='William Shakespeare').annotate(
                     min_price=Min('books__price'))

As that link notes, the order of filter and annotate matters here - because you want to only count books that match the filter in the annotation, the filter must come first.

Daniel Roseman
Oh, I see. This won't just filter out stores without books by Shakespeare, but it'll also affect the subset of books the annotation runs on. Thank you!
Andrew G.