Django: Duplicated logic between properties and queryset annotations

后端 未结 5 984
我寻月下人不归
我寻月下人不归 2020-12-31 10:48

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

5条回答
  •  醉话见心
    2020-12-31 11:37

    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!

提交回复
热议问题