python - F 表达式列表的求和

标签 python django django-models django-aggregation

有没有办法指定(在注释或聚合中)将一系列 F 表达式求和在一起,而无需手动键入 F("first_prop") + F("secondary_prop") + ...?

我想要类似于 python 的 sum() 函数允许您传递可迭代对象并获取可迭代对象中值的总和,即 sum([1,2,3] ) 返回 6

具体来说,我想要看起来像这样的东西:

class Tree(TimeStampedModel):
  leaf_count = models.IntegerField()
  branch_count = models.IntegerField()

Tree.objects.create(leaf_count=60, branch_count=8)
Tree.objects.create(leaf_count=30, branch_count=3)

# now I want to annotate a combined count using my imaginary IterableSum aggregator
combined_sums = list(
  Tree.objects.all().annotate(
    combined_count=IterableSum(fields=[F("leaf_count"), F("branch_count")])
  ).values_list("combined_count", flat=True)
)

combined_sums # [68, 33]

我怎样才能实现这个目标?

最佳答案

sum 的唯一问题是它以 0 开头作为初始值。您可以使用 functools 中的 reduce:

from functools import reduce
from operator import add

from django.db.models import F

combined_sums = list(
    Tree.objects.values(
        combined_count=reduce(add, [F('leaf_count'), F('branch_count')]),
        flat=True,
    )
)

虽然严格来说,这甚至没有必要,但您可以只使用 sum,因为它会将 0F('leaf_count'):

from django.db.models import F

combined_sums = list(
    Tree.objects.values(
        combined_count=sum([F('leaf_count'), F('branch_count')]),
        flat=True,
    )
)

那么查询中将会有一个+ 0,这可能并不理想。

这是因为 sum 仅对整数求和,事实上,您可以例如对 F 对象求和:

In [11]: sum([F('foo'), F('bar')])
Out[11]: <CombinedExpression: Value(0) + F(foo) + F(bar)>

关于python - F 表达式列表的求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75664215/

相关文章:

python - QGis:找到一个点所在的多边形

将十六进制转换为十进制的Python脚本

django LOGIN_REDIRECT_URL 在 nginx ssl 后面不工作

django - 通过中间类保存 ManyToMany

python - shap.Explainer 构造函数错误要求未记录的位置参数

django - 如何使用 tastypie 按用户 ID 过滤对象?

python - django 从查询集上的反向一对多关系添加列

Django 将 self 传递给 models.SET on_delete

python - 如何在 Django 管理更改表单中显示相关表的内容?

python - 第一次使用 Django 数据库 SQL 还是 NoSQL?