pythondjangodjango-templatesdjango-aggregation

Django aggregation. How to render its value into the template?


I have came across on one of the weirdest problem which I literally can't understand. Well I was following This, but nothing helped. As the question says, I just want to render the result into the template. Below is my code.

Views.py

...
    invoice = lead.invoice_set.all()
    total_invoice = invoice.aggregate(total=Sum('amount'))

    context = { 'total_invoice' : total_invoice }

html

{{total_invoice.total}}

This is my code which according to the documentation has to work and as it suggested on the link I've shared. Unfortunately, Its not working for I don't know what reason. Below is what I've tried so far.

TRY 1

When I try to print this into terminal it brings me a dictionary. for example.

print(total_invoice)

prints on terminal...
{'total': 70000}

Which is quite understandable. Now I would want to extract the value and that can be done by simple {{total_invoice.total}}. But it shows nothing on the template.

TRY 2 (Working)

Since I was trying different ways to render the value into the template, I came across this weird solution. I don't know how is this working. What I did different from TRY 1 here is just changing the variable name(total_invoice) to (total) and it worked perfectly fine. Here its how.

Views.py

    invoice = lead.invoice_set.all()
    total = invoice.aggregate(total=Sum('amount'))

    context = { 'total' : total }

html

{{total.total}}

Here its perfectly working by just changing the variable name to total. But then I thought that the name should be same but that's not the case so I tried giving same name to both the variables but this time something other then 'total' but again it did not work. for example

...
total_invoice = invoice.aggregate(total_invoice =Sum('amount'))

What is literally going on I have no idea.

Can any one help me with this. Thank you


Solution

  • If you aggregate, you obtain a dictionary. Indeed, you see:

    {'total': 70000}
    

    You can access the value that corresponds to a key by using {{ variable_name.key }} in the Django template.

    So if you pass it with:

        …
        total_invoice = invoice.aggregate(total_invoice=Sum('amount'))
        …
        render(request, 'some_template.html', {'total_invoice': total_invoice })

    then in the template, you render it with:

    {{ total_invoice.total_invoice }}

    the part before the dot refers to the variable name: the name in the dictionary (in italics), and the second to the key in the dictionary (in boldface).

    If you thus pass it through a variable named total:

        …
        total_invoice = invoice.aggregate(total_invoice=Sum('amount'))
        …
        render(request, 'some_template.html', {'total': total_invoice })

    you render it with:

    {{ total.total_invoice }}

    It might however be more sensical to unpack the dictionary in the view, and thus pass the total as one variable:

        …
        total_invoice = invoice.aggregate(total=Sum('amount'))['total']
        …
        render(request, 'some_template.html', {'total_invoice': total_invoice })

    and then render it with:

    {{ total_invoice }}