Russell Keith-Magee wrote:
> annotate() returns a query set, so it can be used multiple times, be
> combined with filters, etc. The argument handling strategy employed in
> filter() is reused here; kwargs to annotate() can be decomposed on a
> __ boundary to describe table joins, with the last part describing the
> aggregate operator to be used. The syntax follows something like:
>
> Model.objects.annotate(field1__field2__aggregate='annotation')

[snip]

> e.g.,
> # Get order 1234, and annotate it a few different ways
> >>> order = Order.objects.get(id=1234).annotate(
>     books__price__sum='total_cost',
>     books__count='item_count')
> # Inspect the order
> >>> order.description
> "Dad's birthday"
> # Annotated orders have a 'total_cost' attribute...
> >>> order.total_cost
> 47.2
> # ... and an 'item_count' attribute
> >>> order.item_count
> 3

I like making the aggregate function a part of a keyword argument. It
seems consistent with the Django DB API and offers a lot of
flexibility. Better, in my opinion than individual functions for each
aggregator. The 'annotate' name is a little indirect. Maybe something
like 'calc_fields'?

> 3. Just the facts, Ma'am
> ~~~~~~~~~~~~~~~~~~~~~~~~
> Ok; so what if you just want _the minimum_, or _the average_? For
> this, I propose an aggregates() queryset modifier.
>
> >>> Book.objects.aggregates(price__min='min_price', 
> >>> pub_date__max='last_update')
> {'min_price':0.5, 'last_update': 2006-11-22}
>
> aggregates() would expand queries in the same manner as annotate(),
> but would be a terminal clause, just like the values() clause.
>
> This is a more verbose notation than the simple 'max()/min()' . I have
> discussed my problems with these operators previously; however, if
> there is sufficient demand, I don't see any reason that min('field')
> couldn't be included in the API as a shorthand for
> Model.objects.aggregates(field__min='min')['min'].

This seems good, too, but maybe call it 'calc_values' or something with
the 'values' name in it to be consistent with the existing values()
method. The shortcut is nice but I could live without it.

> 4. Comparisons
> ~~~~~~~~~~~~~~
> There is one additional requirement I can see; to perform queries like
> (c), you need to be able to compare annotation attributes to object
> attributes.
>
> # Annotate a query set with the average price of books
> >>> qs = Book.objects.annotate(price__average='avg_price').
> # Filter all books with obj.avg_price < obj.price
> >>> expensive_books = qs.filter(avg_price__lt=F('price'))
>
> The F() object is a placeholder to let the query language know that
> 'price' isn't just a string, it's the name of a field. This follows
> the example of Q() objects providing query wrappers.

To make it more like Q(), would it be better to do
F(avg_price__lt='price') so you could combine them with | and &?


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

Reply via email to