Джанго подсчитать связанные объекты с условием - PullRequest
0 голосов
/ 31 августа 2018

Я хочу отфильтровать результаты перед подсчетом. В приведенном ниже коде я подсчитываю общее количество работников для каждого счетчика билетов.

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.

EDIT: Мои модели:

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 голосов
/ 31 августа 2018

Поскольку , вы можете выполнить фильтрацию в 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=<b>Cast(
            Coalesce(Sum(Value(1) - F('workers__is_deleted')), Value(0))</b>,
            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=<b>Cast(
            Coalesce(Sum(F('workers__is_deleted')), Value(0))</b>,
            IntegerField()
        )
    )
    serializer_class = TicketCounterSerializer
...