Как я могу суммировать содержимое модели django

У меня есть эта модель:

class Transfer(models.Model):
        transfer_code = models.CharField(max_length=30, blank=True, null=True)
        sender_name = models.CharField(max_length=30, blank=True, null=True)
        amount = models.IntegerField(blank=True, null=True)
        recipient_name = models.CharField(max_length=30, blank=True, null=True)
        time_sent = models.DateTimeField(auto_now_add=True, auto_now=False)
        received = models.BooleanField(default=False)
        time_received = models.DateTimeField(auto_now_add=False, auto_now=False, null=True)

        def __unicode__(self):
            return self.transfer_code

Это мое представление, где я хочу рассчитать общую сумму в таблице:

def listtransfersall(request):
    title = 'ALL TRANSFERS'
    queryset = Transfer.objects.all()
    for instance in queryset:
        total = 0
        total += instance.amount
        print total

    context = {
    "title": title,
    "queryset": queryset,
    "total": total,
    }
    return render(request, "listtransfersall.html",context)

Это печатает сумму в таблице индивидуально. Как я могу получить итог и присвоить его общей переменной?


person simplyvic    schedule 20.02.2017    source источник


Ответы (3)


В вашем опубликованном коде вы устанавливаете total = 0 каждый раз в цикле

for instance in queryset:
    total = 0
    total += instance.amount
    print total

Переместите эту строку за пределы цикла, и это будет работать так, как вы предполагали.

Немного лучше было бы получить values_list и суммировать это:

amounts = Transfer.objects.values_list('amount', flat=True)
total = sum(amounts)

Еще лучше было бы позволить базе данных сделать всю работу и использовать агрегацию Sum:

from django.db.models import Sum
total = Transfer.objects.aggregate(Sum("amount"))

Дополнительную информацию об агрегации см. в документации.

person Jon Kiparsky    schedule 20.02.2017

Для этого вы можете использовать аннотацию. В вашем случае попробуйте так:

from django.db.models import Sum

queryset = Transfer.objects.annotate(total_amount=Sum('amount'))

А затем используйте в своем шаблоне:

queryset.total_amount
person Gil Guilherme    schedule 20.02.2017

Я не уверен, что полностью понял ваш вопрос, но я думаю, что ваша проблема в том, что вы объявляете total = 0 внутри своего цикла. Таким образом, он всегда будет равен 0, прежде чем вы добавите значение instance.amount на каждой итерации.

Вы должны объявить total = 0, прежде чем войти в свой цикл, например

total = 0
for instance in queryset:
    total += instance.amount
print total

Этот код добавит instance.amount к переменной total и напечатает общее значение.

person JPYamamoto    schedule 20.02.2017