我需要为多行图形制作一个具有这种主体结构的 API:
[
{
"title": "Test title",
"dots": [
{
"date": "2023-03-03",
"sum_weight": 5000
},
{
"date": "2023-03-06",
"sum_weight": 1500
}
]
}
]
但是我对 Prefetch 有疑问,因为在查询期间不可能使用 .values() 来执行 group_by
date
。现在我未分组的 API 看起来像这样:
[
{
"title": "Test title",
"dots": [
{
"date": "2023-03-03",
"sum_weight": 5000
},
{
"date": "2023-03-06",
"sum_weight": 500
},
{
"date": "2023-03-06",
"sum_weight": 1000
}
]
}
]
我现在的代码:
查询:
groups = Group.objects.prefetch_related(
Prefetch("facts",
queryset=Facts.objects.order_by("date").annotate(sum_weight=Sum("weight")))
)
序列化器:
class GraphDot(serializers.ModelSerializer):
sum_weight = serializers.SerializerMethodField()
def get_sum_weight(self, obj):
if not hasattr(obj, 'sum_weight'):
return 0
return obj.sum_weight
class Meta:
model = Facts
fields = read_only_fields = ("date", "sum_weight",)
class FoodGraphSerializer(serializers.ModelSerializer):
dots = GraphDot(many=True, source="facts")
class Meta:
model = Group
fields = read_only_fields = ("title", "dots")
有什么方法可以进行按
date
分组的查询,以便我的sum_weight
注释在其中求和吗?
感谢@PTomasz 的评论,我在查询中添加了 Window 表达式。
所以最终查询看起来像这样:
groups = Group.objects.prefetch_related(
Prefetch("facts",
queryset=Facts.objects.annotate(
sum_weight=Window(
expression=Sum('weight'),
partition_by=[F('date')],
order_by=OrderBy(F('date'))))
.distinct("date"))
)
没有
.distinct("date")
对象仍在复制,但有正确的sum_weight
(都有1500)。
有了它,一切都很好。