Как выполнить математическую операцию над двумя экземплярами объекта в Django?
Я хочу сложить два числа из двух разных объектов.
Вот упрощенная версия. У меня есть два целых числа, и я перемножаю их, чтобы получить 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...
То, что я пытаюсь сделать, в основном multiplied + multiplied
в шаблоне, но я просто не могу понять, как это сделать, так как сначала мне нужно пройтись по объектам.
Так, если у меня есть 2 экземпляра ModelA
и two 'multiplied' values of 100
, я хочу отобразить 200
в шаблоне. Возможно ли это?
Вы можете попробовать сделать это с помощью aggregate
from django.db.models import Sum
ModelA.objects.aggregate(Sum('multiplied'))
Если это вам не подходит, просто используйте aggregate
на каждом field
и затем сложите их вместе.
В вашем шаблоне, когда вы делаете цикл forloop над переменной numbers
, вы можете напрямую обращаться к свойствам, функциям и атрибутам.
Итак, чтобы получить доступ к нужному вам значению, я полагаю, это будет выглядеть примерно так, упрощенно:
{% for number in numbers %}
{{ number.multiplied }}
{% endfor %}
Надеюсь, это имеет смысл?
Однако учтите, что это не самый эффективный метод.
Мы можем заставить Django попросить SQL-сервер сделать тяжелую работу по вычислениям, так что если вы хотите быть действительно умным и оптимизировать ваше представление, вы можете закомментировать вашу функцию multiplied
и заменить ее, вы все равно получите доступ к ней в шаблоне тем же способом, который я описал выше, но нам нужно немного изменить код в вашем представлении следующим образом:
numbers = ModelA.objects.aggregate(Sum('number_a', 'number_b'))
Подробно описано в ответе Хадуки. Это перегружает вычисления на SQL-сервер путем составления SQL-запроса, который использует функцию базы данных SQL SUM
, что почти всегда будет значительно быстрее, чем наличие функции на объекте.
Хорошей практикой всегда является избегание логики в шаблоне. Лучше сделать цикл в представлении и добавить вычисленное значение в контекст:
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)