我有一个代表两个用户之间交易的模型,如下所示:
class Transaction(models.Model):
buyer = models.ForeignKey(User)
seller = models.ForeignKey(User)
product = models.ForeignKey(Product)
我想获得每个用户(作为买方或卖方)的交易数量。如果我只想依靠一个领域,我可以这样做:
Transaction.objects.values('seller').annotate(Count('seller'))
但我无法在1个查询中同时在两个字段上执行此操作。 有没有办法做到这一点 ?
由于
答案 0 :(得分:2)
我刚刚从我自己那里碰到了这个问题,所以我会发布一个答案,以防万一有人需要它:
显而易见的想法是在单个注释中使用两个Count
,但是作为django doc says,在annotate
中使用多个聚合将产生错误的结果。对于Django 2.2或3,它可以与Count
一起使用distinct
关键字,
from django.db.models import Count
result = Person.objects.annotate(
transaction_count=Count("bought", distinct=True) + Count("sold", distinct=True)
).values("id", "transaction_count")
对于Django <2.2,您可以使用子查询:
from django.db.models import Count, OuterRef, F
buyer_subquery = (
Transaction.objects.filter(buyer_id=OuterRef("id"))
.values("buyer_id")
.annotate(subcount=Count("id"))
.values("subcount")
)
seller_subquery = (
Transaction.objects.filter(seller_id=OuterRef("id"))
.values("seller_id")
.annotate(subcount=Count("id"))
.values("subcount")
)
Person.objects.annotate(
buyer_count=buyer_subquery,
seller_count=seller_subquery,
transaction_count=F("buyer_count") + F("seller_count"),
).values("id", "transaction_count")
答案 1 :(得分:0)
也许这样的事情可行吗?
Transaction.objects.annotate(
num_sellers=Count('seller'), num_buyers=Count('buyer')
)
答案 2 :(得分:0)
过滤器可以引用模型上的字段¶
在目前给出的示例中,我们构建了过滤器,用于比较模型字段的值和常量。但是,如果要将模型字段的值与同一模型上的另一个字段进行比较,该怎么办?
Django提供F表达式以允许这样的比较。 F()的实例充当对查询中的模型字段的引用。然后可以在查询过滤器中使用这些引用来比较同一模型实例上的两个不同字段的值.....
只需参考django文档即可 https://docs.djangoproject.com/en/1.11/topics/db/queries/