I want to add two numbers from two different objects.
Here is a simplified version. I have two integers and I multiply those to get multiplied
.
models.py:
class ModelA(models.Model):
number_a = models.IntegerField(default=1, null=True, blank=True)
number_b = models.IntegerField(default=1, null=True, blank=True)
def multiplied(self):
return self.number_a * self.number_b
views.py:
@login_required
def homeview(request):
numbers = ModelA.objects.all()
context = {
'numbers': numbers,
}
return TemplateResponse...
What I'm trying to do is basically multiplied multiplied
in the template but I simply can't figure out how to do it since I first have to loop through the objects.
So if I had 2 instances of ModelA
and two 'multiplied' values of 100
I want to display 200
in the template. Is this possible?
CodePudding user response:
In your template, when you do a forloop over the numbers
variable, you can directly access properties, functions and attributes.
So to access the value you want I guess it would look something like this, simplified:
{% for number in numbers %}
{{ number.multiplied }}
{% endfor %}
Hope that makes sense?
However, please take note that this is not the most efficient method.
We can make Django ask the SQL server to do the heavy lifting on the calculation side of things, so if you want to be really clever and optimise your view, you can comment out your multiplied
function and replace then, you still access it in the template the same way I described above, but we needs to change the code in your view slightly like so:
numbers = ModelA.objects.aggregate(Sum('number_a', 'number_b'))
As described loosely in haduki's answer. This offloads the calculation to the SQL server by crafting an SQL query which uses the SUM
SQL database function, which for all intents and purposes is almost always going to be substantially faster that having a function on the object.
CodePudding user response:
The good practice is always to avoid logic on the template. It would be better to loop at the view and add calculated value to context:
def homeview(request):
queryset = ModelA.objects.all()
multipliers_addition = 0
for obj in queryset:
multipliers_addition = obj.multiplied()
context = {
'addition': multipliers_addition,
}
return render(request, 'multiply.html', context)
CodePudding user response:
You can try doing that with aggregate
from django.db.models import Sum
ModelA.objects.aggregate(Sum('multiplied'))
If that does not suit you just use aggregate
on each field
and then add them together.