用django计数和Q / F查询

时间:2016-07-10 11:22:01

标签: django count django-queryset

我想使用带有Count的Q / F对象,我收到以下错误:

int() argument must be a string or a number, not 'Count'

我想得到所有的交易:

  • start_date是过去或今天的日期
  • end_date是将来或今天的日期或者数量 参与(DealsParticipation模型)低于最大值 交易参与者人数(字段nb_participants)。

我的模特:

class Deals(models.Model):
    u"""List of deals available to the participant 
    """

    brand = models.ForeignKey(Brand_Advertiser, blank=False, null=False, related_name='brands_of_deal')
    start_date = models.DateField(_("Date de debut"), blank=False, null=False, default=datetime.date.today)
    end_date = models.DateField(_("Date de fin"), blank=True, null=True)
    nb_participants=models.PositiveIntegerField(_("Nombre de participants maximum"), default=100, blank=True, null=True)


class DealsParticipation(TimeStampedModel):

    u"""Participation to deals by participants
    """

    deal = models.ForeignKey('Deals', blank=False, null=False, related_name='deal_participation')
    participant = models.ForeignKey(Participant, blank=False, null=False)

我尝试过:

class CurrentDealsView(ListView):
    model = models.Deals

    def get_queryset(self):
        #get all the deals having started in the past or today and closing in the future or today
        now = datetime.now()
        start_date_condition=Q(start_date__lte=now)
        end_date_condition = Q(end_date__gte=now) | Q(end_date__isnull=True)
        #get all the deals with a number of participations lower than the maximal number of participants
        nb_participants_condition=Q(nb_participants__gt=Count('deal_participation'))
        return models.Deals.objects.filter(start_date_condition & (end_date_condition | nb_participants_condition))

解决!

正如emulbreh所解释的那样,我不得不在注释中使用计数:

def get_queryset(self):
    #get all the deals having started in the past or today and closing in the future or today
    now = datetime.now()
    start_date_condition=Q(start_date__lte=now)
    end_date_condition = Q(end_date__gte=now) | Q(end_date__isnull=True)
    date_conditions=models.Deals.objects.filter(start_date_condition & end_date_condition)

    #get all the deals with a number of participations lower than the maximal number of participants
    return date_conditions.annotate(participation_count=Count('deal_participation')).filter(nb_participants__gt=F('participation_count'))

1 个答案:

答案 0 :(得分:1)

聚合函数(如Count)需要与annotate()aggregate()一起使用。您可以引用filter()Q()注释的字段:

Deals.objects.annotate(
    participation_count=Count('deal_participation')
).filter(
    nb_participants__gt=F('participation_count')
)

有一个example in the Django docs