Search code examples
pythondjangodjango-tables2

Django-tables2 footer sum of computed column values


Is there a way to get the sum of values of a column which contains computed values? I tried rendering the footer following the documentation and a question here, but without results.

EDIT:

class BillsColumn(Column):
    def render(self, record):
        bills = record.certificatebills.all()
        total_bill = 0
        for bill in bills:
            total_bill += bill.bill_amount
        return(round(total_bill, 2))

    def render_footer(self, bound_column, table):
        column_values = sum(columns_somehow)
        return column_values

This is the custom column I'm using. It returns the sum of certificate bills of of each certificate and then shows it in the Column. I don't know how to access this computed value in the render_footer method.


Solution

  • You could accumulate the total_bill in a class attribute, using something like this:

    class BillsColumn(Column):
        column_total = 0
    
        def render(self, record):
            bills = record.certificatebills.all()
            total_bill = 0
            for bill in bills:
                total_bill += bill.bill_amount
            # accumulate
            self.column_total += total_bill
            return round(total_bill, 2)
    
        def render_footer(self, bound_column, table):
            return round(self.column_total, 2)
    

    Depending on how much bills your records have, it might be more efficient to let de database do the calculation. This is called aggregation, and might look like this:

    from django.db.models import Sum
    
    class BillsColumn(Column):
        column_total = 0
    
        def render(self, record):
            total = record.certificatebills.aggregate(total=Sum("bill_amount"))['total']
            self.column_total += total
            return total
    
        def render_footer(self, bound_column, table):
            return round(self.column_total, 2)
    

    If your table is paginated, the value in the footer only represents the bills for records in the current page. If you want to sum over all pages, you'll have to use an aggregation over all bill_amounts for all records in the table.