当我写Django子查询表达式时,有时我不知道Django如何对结果进行分组。
示例:
subquery = (
RelatedModel.objects.filter(
category="some_category",
grandparentmodel=OuterRef("relatedmodel__grandparentmodel"),
mymodel__created_at__date=OuterRef("created_at__date"),
)
.values("grandparentmodel", "mymodel__created_at__date")
.annotate(net=Sum("mymodel__amount"))
.values("net")[:1]
)
query = (
MyModel.objects.annotate(
net=Coalesce(
Subquery(subquery), Decimal("0.00")
)
)
)
这样,我的目标是将一堆ParentModel
示例(类别为"some_category"
)按grandparentmodel
和mymodel__created_at__date
分组。
这似乎只有在注解之前包含.values("mymodel__created_at__date")
时才有效。如果我在net
的注解之前没有包含它,子查询仍然运行,只是给出了不正确的net
。但是,.values("grandparentmodel")
似乎不需要得到正确的分组;我可以排除它,我仍然得到我期望的值。
幕后发生了什么?我如何知道在注解之前使用.values()
调用来正确分组?我怎么知道在values()
调用中要包括什么?在聚合子查询时,是否有一些经验法则要遵循?
1条答案
按热度按时间tf7tbtn21#
通常,ORM不是用来构造精确的SQL查询的。它更像是一个工具,可以将您的需求转录成它所能找到的最佳查询。
但是,你找到的是强制分组的方法。
.values()
本身将丢弃Model层,并将查询集结果更改为包含作为参数给出的键的dicts。后面是
.annotate()
,它包含一个不在.values()
参数中的字段上的聚合函数,它将导致一个group by。结果也将是dicts