Как вернуть несколько агрегатов на основе условия в наборе запросов?

У меня есть следующая модель, которая содержит различные булевы и одно поле amount. Теперь я хочу вывести общую сумму amount для каждого булева, когда оно истинно (только одно булево будет истинным одновременно всегда).

class UserTransaction(models.Model):
    """
    A table to store transactions between a user and Farena
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    offer = models.ForeignKey(Offer, on_delete=models.CASCADE, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    amount = models.FloatField()
    is_deposit = models.BooleanField(default=False)
    is_withdrawal = models.BooleanField(default=False)
    is_interest = models.BooleanField(default=False)
    is_investment = models.BooleanField(default=False)
    is_return = models.BooleanField(default=False)

    def __str__(self):
        return f'{self.user.first_name} {self.user.last_name} transacted {self.amount}'

Я пытался построить его с помощью annotate, но это добавило бы поля для каждого экземпляра, что не решило бы мою проблему, насколько я понимаю. Кроме того, используя aggregate я не смог бы реализовать условие, а также не знал бы, как получить доступ к агрегированному значению в шаблоне?

Вы можете агрегировать по всем полям, так:

UserTransaction.objects.aggregate(
    total_deposit=Sum('is_deposit'),
    total_withdrawal=Sum('is_withdrawal'),
    total_interest=Sum('is_interest'),
    total_investment=Sum('is_investment'),
    total_return=Sum('is_return')
)

или для некоторых баз данных, где bool не реализован как целое число:

UserTransaction.objects.aggregate(
    total_deposit=Count('pk', filter=Q(is_deposit=True)),
    total_withdrawal=Count('pk', filter=Q(is_withdrawal=True)),
    total_interest=Count('pk', filter=Q(is_interest=True)),
    total_investment=Count('pk', filter=Q(is_investment=True)),
    total_return=Count('pk', filter=Q(is_return=True))
)

Это вернет словарь, который будет выглядеть следующим образом:

{
    'total_deposit': 14,
    'total_withdrawal': 25,
    'total_interest': 13,
    'total_investment': 2
    'total_return': 17
}
Вернуться на верх