Django按字段总和排序

14

是否可以使用Django ORM按两个不同字段的总和对查询结果进行排序?

例如,我有一个模型如下:

class Component(models.Model):
    material_cost = CostField()
    labor_cost = CostField()

我想做类似这样的事情:

component = Component.objects.order_by(F('material_cost') + F('labor_cost'))[0]

但是不幸的是,F对象似乎不能与 'order_by' 一起使用。在 Django 中是否有这样的可能性?


https://dev59.com/UnRB5IYBdhLWcg3w4bOv#476033 - Pavel Strakhov
不太符合我的要求。该方法在所有相关对象中对某个字段进行求和。(在这个特定的例子中,它对所有相关投票的值进行求和。)我需要对原始对象上的两个字段进行求和。因此,除非有我不知道的使用方法,否则我不能使用Sum聚合器。 - So8res
4个回答

20
你可以使用extra来实现这个功能。
Component.objects.extra(
    select={'fieldsum':'material_cost + labor_cost'},
    order_by=('fieldsum',)
)

请见文档


这对我不起作用,但是 Component.objects.extra(select={'fieldsum':'material_cost + labor_cost'}).order_by=('fieldsum') 可以。 - Bikash kharel
1
现在你应该真正使用annotate: Component.objects.annotate(fieldsum=F('material_cost') + F('labor_cost')).order_by('fieldsum') - Daniel Roseman

15

我认为现在是提供更好答案的时候了。由于Django团队正在考虑废弃extra(),使用annotate()F()表达式更好:

from django.db.models import F

Component.objects.annotate(fieldsum=F('material_cost') + F('labor_cost')).order_by('fieldsum')

另请参阅https://code.djangoproject.com/ticket/25676


2

使用extra:

Component.objects.extra(select = {'total_cost' : 'material_cost + labor_cost'},
                                   order_by = ['total_cost',])[0]

0

现在您可以直接在order_by中使用F()表达式,您建议的代码应该可以正常工作:

component = Component.objects.order_by(F('material_cost') + F('labor_cost'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接