I wanted a "sum" of a particular column being listed in the admin list
page. I looked it up and did it the following way. Is this the correct
way of doing it?
I modified the admin.py to do the calculation:
class CollectionAdmin(admin.ModelAdmin):
list_display = ('supplier', 'collected_date', 'tonnage',)
list_filter = ('collected_date',)
def changelist_view(self, request, extra_context=None):
from django.contrib.admin.views.main import ChangeList
from django.db.models import Sum
if extra_context is None:
extra_context = {}
mycl = ChangeList(request, self.model, list(self.list_display),
self.list_display_links, self.list_filter, self.date_hierarchy,
self.search_fields, self.list_select_related, self.list_per_page,
self.list_editable, self)
fieldsum = mycl.get_query_set().aggregate(Sum('tonnage'))
extra_context['tonnage__sum'] = fieldsum['tonnage__sum']
return super(CollectionAdmin, self).changelist_view(request,
extra_context=extra_context)
then i added the following line to change_list.html:
{% if tonnage__sum %}Total tonnage: {{ tonnage__sum }}{% endif
%}
Am I doing something bad in the changelist_view function above? Or is
it the right way to do this?
the reason I want to use the admin list is because I like the
filtering option, and I can then see directly the sum of the column
based on whatever is currently filtered.
Thanks.
On Dec 20, 2:54 am, yummy_droid <yus...@gmail.com> wrote:
> Hi,
>
> I wanted a "sum" of a particular column being listed in theadminlist
> page. I looked it up and did it the following way. Is this the correct
> way of doing it?
>
> I modified theadmin.py to do the calculation:
>
> class CollectionAdmin(admin.ModelAdmin):
> list_display = ('supplier', 'collected_date', 'tonnage',)
> list_filter = ('collected_date',)
>
> defchangelist_view(self, request, extra_context=None):
> from django.contrib.admin.views.main import ChangeList
> from django.db.models import Sum
> if extra_context is None:
> extra_context = {}
> mycl = ChangeList(request, self.model, list(self.list_display),
> self.list_display_links, self.list_filter, self.date_hierarchy,
> self.search_fields, self.list_select_related, self.list_per_page,
> self.list_editable, self)
> fieldsum = mycl.get_query_set().aggregate(Sum('tonnage'))
> extra_context['tonnage__sum'] = fieldsum['tonnage__sum']
> return super(CollectionAdmin, self).changelist_view(request,
> extra_context=extra_context)
>
> then i added the following line to change_list.html:
>
> {% if tonnage__sum %}Total tonnage: {{ tonnage__sum }}{% endif
> %}
>
> Am I doing something bad in thechangelist_viewfunction above? Or is
> it the right way to do this?
>
> the reason I want to use theadminlist is because I like the
Not really. Your solution is probably the best that can be done - it
does involve instantiating the ChangeList twice, but that's pretty
much unavoidable. One of the main criticisms a lot of people have of
the (otherwise wonderful) admin application is that a lot of the
methods are pretty monolithic - there aren't many hooks that you can
use to override small bits without having to repeat the whole method.
That said, here's an option that just occurred to me. The template has
access to the changelist object, which you use to get the query set to
calculate the aggregate. So you can use that `cl` via the template by
writing a template tag that takes that as a parameter, gets the
queryset and adds the aggregate value.
--
DR.
I just tried your way and it worked great. It's an easy and quick
solution for summing up columns.
I don't know if there is a better way to do it.
Thank you, you saved me a lot of time