Reputation: 23
I am extremely newbie to Django, Sorry in the advance for asking the wrong question.
I want to create a function to sum the values of a column and call it on my template in Django.
Model:
class Invoice(models.Model):
product_name = models.CharField(max_length=255)
purchase_date = models.DateTimeField(auto_now=True)
cost_price = models.IntegerField()
selling_price = models.IntegerField()
@property
def get_total(self):
amount = Invoice.objects.aggregate(Sum('selling_price'))
return amount
I created this get_total function to sum of the values of selling_price column.
Template Code:
{% for item in query_result %}
<tr>
<td>{{item.product_name}}</td>
<td>{{item.cost_price}}</td>
<td>{{item.selling_price}}</td>
{{item.get_total}}
</tr>
{% endfor %}
Here's the problem, after passing the data, whenever I call this function, the data is shown multiple times in the template.
Here's the output. Output Image
I know it's quite silly, but I am unable to figure it out.
Help, Please.
Upvotes: 2
Views: 1128
Reputation: 3327
You can directly annotate
the aggregation
, for example:
Invoice.objects.aggregate(amount = Sum('selling_price'))
The resulting dictionary will have a key called amount
. If no such alias were specified, it would be the rather long selling_price__sum
Since it returns a dict, you can get the value through:
class YourModel(models.Model):
@property
def get_total(self):
amount = Invoice.objects.aggregate(amount = Sum('selling_price'))['amount']
return amount
# template
{{ item.get_total }} would only get amount value out, not dict
BTW:
Adding extra manager methods is the preferred way to add “table-level” functionality to your models. (For “row-level” functionality – i.e., functions that act on a single instance of a model object
Aggregation is a table level function, since it calculate the sum of multiple objects, which is better defined as manager method
instead at model instance level.
class InvoiceManager(models.Manager):
def get_total(self):
return self.aggregate(amount = Sum('selling_price'))['amount']
class Invoice(models.Model):
product_name = models.CharField(max_length=255)
purchase_date = models.DateTimeField(auto_now=True)
cost_price = models.IntegerField()
selling_price = models.IntegerField()
# customized manager
objects=InvoiceManager()
def your_view(request):
...
context = {
'query_result': Invoice.objects.all()
'amount': Invoice.objects.get_total()
}
return render(request, 'index.html', context)
Upvotes: 3