>> I haven't yet figured out a way to suppress the order_by portion, >> so what's currently in there is an ugly hack. But it would need >> to prevent the standard methods from inserting an ORDER BY clause >> against a non-aggregated field. > > if you add an empty call (no parameters) to order_by(), it will drop > the ORDER BY clause
I thought I had tried this. I'll have to give it another whack on Monday when I get back from PyCon. I had problems with it trying to order the resultset by the Meta.ordering properties, when those fields weren't part of the aggregate. I'll try it again to see if I did something wrong or if I unearthed a bug. > I have another proposition, how about: > >>>> quseryset = Model.objects.all() >>>> queryset.aggregate( ( 'name', 'city' ), sum=( 'pay', > 'some_other_field' ), avg=( 'pay', 'age' ), count=True ) I like this calling interface as an alternate method for its fine-tuned control, but there are times it would be nice to not have to have such tight coupling between the model and the aggregation. Otherwise, a change in the model requires not only a change in the template to make use of the results, but in the view (to request various aggregate functions) to add the desired aggregation functions. >>>> [ > { > 'name' : 'some name', > 'city' : 'Prague', > 'sum' : { 'pay' : 30000, 'some_other_field' : 10000 }, > 'avg' : { 'pay' : 10000, 'age' : 30 }, > 'count' : 5, > }, > ...... > ] As long as the resulting data can be easily accessed directly by a template, any number of resulting formats would work just fine. I'd see using it something like return render_to_response( 'test.html', {'items': Model.objects.all()} ) and then within the template refer to <table> {% for item in items %} <tr><td>{{ item.pay }}</td></tr> {% endfor %} <tr><td>{{ items.aggregate.sum.pay }}</td></tr> </table> or possibly items = Model.objects.all() return render_to_response('test.html', { 'items': items, 'stats': items.aggregate(), }) and then within the template refer to <table> {% for item in items %} <tr><td>{{ item.pay }}</td></tr> {% endfor %} <tr><td>{{ stats.sum.pay }}</td></tr> </table> > it seems reasonably clean interface to me: > fist argument is a tuple of fields on which to call GROUP BY, then > there are several optional kwargs: avg, sum, min, max and count > > I am willing to code up a patch for this, it should be pretty > straightforward. If we would want to take it to the next level, we > could allow filter() on such aggregated queryset, that would manifest > itself in the HAVING clause... > > what do you think?? I like the ideas you present, particularly your clean interface for the aggregated results ("results.sum.fieldname" rather than my munged "results.fieldname_sum") and the clean interface for specific aggregation. However, as stated above, I am hesitant to give up the simplicity of just asking for "aggregate everything possible" to prevent tight coupling. Both sound good to me ("but I want both specific *and* generic" :) Feel free to swipe any of the code I provided for any patches you make. I think it will be a valuable addition as evaluation can be made lazy (thus, it has no great impact on existing code), and I've seen it requested several times in the Django-Users ML archives where the answer was "Django doesn't do that, but you can drop to hand-rolled SQL to do it for you." I think it would help the folks that don't think in SQL. Just my musings...I appreciate your feedback. -tkc --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@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-users?hl=en -~----------~----~----~----~------~----~------~--~---