Reputation: 325
I'm using Django to make a website. I want to combine multiple filter results (Querysets).
My models' relationship
'Staff' 1:m 'Member' 1:m 'PaymentHistory' 1:1 'RefundHistory'
My view.py:
wanted_refund = set()
for m in staff.members.all():
payment = m.PaymentHistory.filter(division="Membership")
for p in payment:
try:
refund = RefundHistory.objects.filter(payment=p).filter(refund_date__range=[this_month_start, date])
wanted_refund.add(refund)
except RefundHistory.DoesNotExist:
pass
context = {
'wanted_refund' : wanted_refund,}
return render(request, 'refund.html', context)
But, it doesn't work by using filters. It only works when I use 'get'.
print(refund)
shows me the result like this:
< QuerySet [] >
< QuerySet [] >
< QuerySet [] >
< QuerySet [< RefundHistory: RefundHistory object >] >
I want to use only the Querysets that have the object and what I want is the below one in template:
{% for refund in wanted_history %}
{{ refund.refund_date }}
{{ refund.refund_amount}}
{% endfor %}
How do I pass over the multiple filters results in for loop?
Upvotes: 1
Views: 1028
Reputation: 2884
It is possible to get the refund history for every payment of every member using a single query of the RefundHistory
:
payments = []
for m in staff.members.all():
payments.extend(m.PaymentHistory.filter(division="Membership").values_list('pk', flat=True))
wanted_refund = RefundHistory.objects.filter(payment__pk__in=payments, refund_date__range=[this_month_start, date])
context = {'wanted_refund' : wanted_refund,}
return render(request, 'refund.html', context)
Upvotes: 1
Reputation: 1844
You could join querysets using pipe operator:
wanted_refund = RefundHistory.objects.none()
for m in staff.members.all():
payment = m.PaymentHistory.filter(division="Membership")
for p in payment:
try:
wanted_refund |= RefundHistory.objects.filter(payment=p).filter(refund_date__range=[this_month_start, date])
except RefundHistory.DoesNotExist:
pass
wanted_refund = wanted_refund.distinct()
context = {'wanted_refund': wanted_refund}
return render(request, 'refund.html', context)
Also, if it will work for you, you may just use wanted_refund.update(list(refund))
in place of wanted_refund.add(refund)
Upvotes: 3