0

I have two models in our django app

class Reg(models.Model):
   transactions = ManyToMany
   price = IntegerField

class Transaction(models.Model)
   amount = IntegerField

Now I would like to make a lookup like:

Registration.objects.filter(reg__price==transaction__amount)

Previously we used the following approach:

  • Registration has a property is_paid that computes wether a transaction with equal amount exists
  • [r for r in Registration.objects.filter(...) if r.is_paid]

This is ofc very query-consuming and inefficient. I wonder whether there would be a better way to do this! Any hint is appreciated :)

3
  • You did not construct the fields, you should write IntegerField() and ManyToMany('Transaction'). Commented Jan 19, 2018 at 13:22
  • Furthermore it is not very clear when an invoice is paid? If the sum of the transactions sum up to amount? Commented Jan 19, 2018 at 13:23
  • @WillemVanOnsem this was obviously pseudo-code. For the second though, well, if enough transaction amount exists to cover the price == paid Commented Jan 19, 2018 at 13:28

1 Answer 1

2

You can use an F expression for such a query:

from django.db.models import F

Registration.objects.filter(price=F('transactions__amount'))

This will filter all Registration instances whose price is equal to one of their transactions' amount. If you want all transactions amounts' sum to be equal or more than the registration price, you can use annotations to aggregate each registration's Sum:

paid_registrations = Registration.objects.\
   annotate(ta=Sum('transactions__amount')).\  # annotate with ta sum
   filter(price__lte=F('ta'))  # filter those whose price is <= that sum
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.