When I want to define my business logic, I\'m struggling finding the right way to do this, because I often both need a property AND a custom queryset to get the same info. I
Let this be the alternative way to archive what you want:
Since I usually add the prefetch_related every time I write a queryset. So when I face this problem, I will use Python to solve this problem.
I'm going to use Python to loop and count the data for me instead of doing it in SQL way.
class PickupTimeSlot(models.Model):
@property
def nb_bookings(self) -> int:
""" How many times this time slot is booked? """
orders = self.order_set.all() # this won't hit the database if you already did the prefetch_related
validated_orders = filter(lambda x: x.status == Order.VALIDATED, orders)
return len(validated_orders)
And most important thing, prefetch_related:
time_slots = PickupTimeSlot.objects.prefetch_related('order_set').all()
You may have a question that why I didn't prefetch_related with filtered queryset so Python doesn't need to filter again like:
time_slots = PickupTimeSlot.objects.prefetch_related(
Prefetch('order_set', queryset=Order.objects.filter(status=Order.VALIDATED))
).all()
The answer is there are sometimes that we also need the other information from orders as well. Doing the first way will not cost anything more if we're going to prefetch it anyway.
Hope this more or less helps you. Have a nice day!