使用 Prefetch 与 related_name 关系分组

问题描述 投票:0回答:1

我需要为多行图形制作一个具有这种主体结构的 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
注释在其中求和吗?

python django api django-rest-framework django-queryset
1个回答
1
投票

感谢@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)。

有了它,一切都很好。

© www.soinside.com 2019 - 2024. All rights reserved.