在Django 1.11中计算子查询的行数

时间:2017-09-11 10:15:21

标签: python django django-orm

我有几个型号

class Order(models.Model):
    user = models.ForeignKey(User)

class Lot(models.Model):
    order = models.ForeignKey(Order)
    buyer = models.ForeignKey(User)

我尝试做的是使用给定用户向同一卖家进行多次购买来注释Lot个对象。 (这不是一个错误,Order.user实际上是卖家)。就像“你最近从这个用户那里买了4件物品”。

我最接近的是

recent_sold_lots = Lot.objects.filter(
    order__user_id=OuterRef('order__user_id'),
    status=Lot.STATUS_SOLD,
    buyer_id=self.user_id,
    date_sold__gte=now() - timedelta(hours=24),
)

qs = Lot.objects.filter(
    status=Lot.STATUS_READY,
    date_ready__lte=now() - timedelta(seconds=self.lag)
).annotate(same_user_recent_buys=Count(Subquery(recent_sold_lots.values('id'))))

但是当recent_sold_lots计数多于一个时,它会失败:由用作表达式的子查询返回的多行。

.annotate(same_user_recent_buys=Subquery(recent_sold_lots.aggregate(Count('id')))似乎也不起作用:此查询集包含对外部查询的引用,并且只能在子查询中使用。

.annotate(same_user_recent_buys=Subquery(recent_sold_lots.annotate(c=Count('id')).values('c'))正在给我 Expression包含混合类型。您必须设置output_field。。如果我将output_field=models.IntegerField()添加到子查询调用中,它会抛出由用作表达式的子查询返回的多行。

我坚持这个。我觉得我接近解决方案,但我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

您在问题中定义的模型无法正确反映您正在进行的查询。在任何情况下,我都会使用该模型作为我的查询的参考。

from django.db.models import Count

user_id = 123 # my user id and also the buyer
buyer = User.objects.get(pk=user_id)

Lot.objects.filter(buyer=buyer).values('order__user').annotate(unique_seller_order_count=Count('id'))

查询的作用是:

  1. 将批次对象过滤为已购买的对象
  2. 将退回的拍品分组到创建订单的用户
  3. 注释/计算每个组的回复