【问题标题】:Django count related objects with conditionDjango根据条件计算相关对象
【发布时间】:2019-02-06 16:10:16
【问题描述】:

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

class TicketCounterList(ListAPIView):
    queryset = TicketCounter.objects.filter(ticket_counter_is_deleted=False)
            .annotate(num_workers=Count('workers'))
    serializer_class = TicketCounterSerializer

上述代码中的workers 是来自另一个模型(WorkerToTicketCounter 模型)的related_name。我想要做的是,我希望能够过滤条件为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',
        )

【问题讨论】:

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


【解决方案1】:

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

然而我们可以做的是总结workers__is_deleted,或者它的否定。例如,如果我们想要返回删除的工人数量:

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

【讨论】:

  • 感谢您再次回复。我收到 CoalesceV 的导入错误。
  • @Naroju:是的,我认为 Django 库中有一些重命名和变动。它现在可能已经修复了。
  • 小疑问。我可以注释另一个模型的另一个related_name 以进行计数。像链接..?
  • 同时计算不同的相关对象通常效率低下,而且很危险,因为不同的连接可以充当乘数
  • 是的。那怎么办呢?
猜你喜欢
  • 2020-05-08
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2021-11-24
相关资源
最近更新 更多