Django计算条件下的相关对象

时间:2018-08-31 15:28:10

标签: django django-models django-rest-framework

我想在计数之前过滤结果。在下面的代码中,我正在计算每个售票柜台的工人总数。

class TicketCounterList(ListAPIView):
    queryset = TicketCounter.objects.filter(ticket_counter_is_deleted=False)
            .annotate(num_workers=Count('workers'))
    serializer_class = TicketCounterSerializer
上面的代码中的

workers是来自另一个模型(related_name模型)的WorkerToTicketCounter。我想做的是,我希望能够过滤条件为is_deleted= True的工人,而不是计算所有工人。可能吗?我正在使用Django 1.11.13

下面有什么

queryset = TicketCounter.objects.filter(ticket_counter_is_deleted=False)
            .annotate(num_workers=Count('workers',filter="xxxx"))

明白吗?我要过滤workers

编辑: 我的模特:

class TicketCounter(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    ticket_counter_name = models.CharField(max_length=100, default="")
    ticket_counter_description = models.CharField(max_length=1500, default="")
    ticket_counter_address = models.CharField(max_length=1500, default="")


class WorkerToTicketCounter(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    ticket_counter = models.ForeignKey(TicketCounter,related_name="workers")
    worker = models.ForeignKey(User,related_name='worker_for_ticket_counter')

我的序列化器:

class TicketCounterSerializer(serializers.ModelSerializer):
    num_workers = serializers.IntegerField()
    class Meta:
        model = TicketCounter
        fields = (
            'ticket_counter_name',
            'ticket_counter_description',
            'ticket_counter_address',
            'num_workers',
        )

1 个答案:

答案 0 :(得分:1)

起,您可以在Count中进行过滤,但这对我们没有帮助。

我们 所能做的就是在workers__is_deleted上的 sum 或其取反。例如,如果我们要返回删除的工作人员数量:

from django.db.models import F, IntegerField, Sum, Value
from django.db.models.functions import Coalesce

class TicketCounterList(ListAPIView):
    queryset = TicketCounter.objects.filter(
        ticket_counter_is_deleted=False
    ).annotate(
        num_workers=Cast(
            Coalesce(Sum(Value(1) - F('workers__is_deleted')), Value(0)),
            IntegerField()
        )
    )
    serializer_class = TicketCounterSerializer

或者如果您要计算已删除的工作人员:

from django.db.models import F, IntegerField, Sum, Value
from django.db.models.functions import Coalesce

class TicketCounterList(ListAPIView):
    queryset = TicketCounter.objects.filter(
        ticket_counter_is_deleted=False
    ).annotate(
        num_workers=Cast(
            Coalesce(Sum(F('workers__is_deleted')), Value(0)),
            IntegerField()
        )
    )
    serializer_class = TicketCounterSerializer