Как выполнить математическую операцию над двумя экземплярами объекта в 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)
Вернуться на верх