Kihaf
Kihaf

Reputation: 77

Django annotate sum on fk_set

I'm trying to annotate sum of fields in related set:

My models:

class Report(models.Model):

class ReportCommissionPosition(models.Model):
    report = models.ForeignKey(Report)
    reservation = models.OneToOneField("reservations.Reservation")

class Reservation(models.Model):

class Payment(models.Model):
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    reservation = models.ForeignKey('reservations.Reservation')
    PAYMENT_TYPES=(
        ('TRANS', 'TRANS'),
        ('SELL', 'SELL'),
    payment_accounting_type = models.CharField(max_length=50, choices=PAYMENT_TYPES)

I need to annotate each position of report.reportcommissionposition_set with two fields:

trans_amount - Sum of all the payments with payment accounting type == 'SELL' (through reservation => payment) sum_amount - Sum of all the payments with payment accounting type == 'TRANSFER' (through reservation => payment)

I have tried:

for position in commission_position:
    position.sell_pay = position.reservation.payment_set.filter(payment_accounting_type='SELL').aggregate(amount=Sum('amount'))['amount']

But this creates new query for every element.

Any thoughts?

Upvotes: 1

Views: 46

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476584

You can annotate these with:

myreport.reportcommissionposition_set.annotate(
    trans_amount=Sum(
        'reservation__payment__amount',
        filter=Q(reservation__payment__type='SELL')
    ),
    sum_amount=Sum(
        'reservation__payment__amount',
        filter=Q(reservation__payment__type='TRANS')
    )
)

the ReportCommissionPosition objects of myreport will have two extra fields: .trans_amount and .sum_amount with the sums of the SELL and TRANS payments respectively.

Upvotes: 3

Related Questions