我发现了一些与我的问题相似的问题,但其中大多数都过时了,或者太(或太少)冗长而无济于事。
我有一个这样的模型:
class Breakfast(models.Model):
count_eggs = models.IntegerField()
count_bacon = models.IntegerField()
had_toast = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)
现在,在构建 RESTful API 时,我需要能够按总数对早餐对象进行排序,count_eggs + count_bacon而无需将其永久存储在模型中。
许多当前和流行的问题都暗示了这样的事情:
Breakfast.objects.extra(
select={'total_food':'count_eggs + count_bacon'},
order_by=('total_food',)
)
Run Code Online (Sandbox Code Playgroud)
这似乎对许多人有效,但Django 文档似乎劝阻此解决方案。因此,在 1.10+ 世界中,对 Django 中的两个(或多个)字段的总和进行此类过滤的最佳/正确方法是什么?
你应该使用注释,我有一个我的例子并适应你的情况,试试这个:
from django.db.models import F, Sum
Breakfast.objects.all().\
annotate(total_food=Sum(
F('count_eggs ') + F('count_bacon'))
).\
order_by('total_food')
Run Code Online (Sandbox Code Playgroud)
Latrovas 的答案略有更正,尽管他的查询可以工作,但不需要 SUM 和 GROUP_BY。
更直观的查询如下:
Breakfast.objects.all().\
annotate(total_food=F('count_eggs ') + F('count_bacon')
).order_by('total_food')
Run Code Online (Sandbox Code Playgroud)
我想更进一步向您解释查询在幕后如何工作:
当我们注释时,我们本质上是在SELECTSQL 语句中添加一列。因此,要执行两个字段的相加,我们需要一个像这样的 select 语句SELECT (eggs + bacon) as food。
这正是幕后annotate所做的事情。
但我们不需要使用硬编码值,而是需要使用存储在数据库中的项目,即列名eggs和bacon表达式。
这正是表达式的作用F()。
现在,您迟早会意识到,由于它们做了两种完全不同的事情,因此我们可以轻松地将两者结合起来,并将它们一起用于一些真正强大的东西!
| 归档时间: |
|
| 查看次数: |
3832 次 |
| 最近记录: |