序言
这是SO中经常出现的问题:
也可以在这里应用:
我已经在SO文档中编写了一个示例,但由于文档将于2017年8月8日关闭,我将遵循this widely upvoted and discussed meta answer的建议并将我的示例转换为自我回答的帖子。
当然,我也很高兴看到任何不同的方法!!
问题:
假设以下型号:
class MyModel(models.Model):
number_1 = models.IntegerField()
number_2 = models.IntegerField()
date_1 = models.DateTimeField()
date_2 = models.DateTimeField()
如何在此模型的字段之间执行算术运算?
例如,我该如何找到:
number_1
和number_2
的乘积?date_2
比date_1
早10天或以上的项目?答案 0 :(得分:8)
F()
表达式可用于在模型字段中执行算术运算(+
,-
,*
等),以便定义代数查找/连接他们之间。
F()
对象表示模型字段或带注释列的值。它可以引用模型字段值并使用它们执行数据库操作,而无需将它们从数据库中拉出到Python内存中。
让我们解决问题:
两个字段的产物:
result = MyModel.objects.all().annotate(prod=F('number_1') * F('number_2'))
现在result
中的每个项目都有一个名为'prod'的额外列,其中包含每个项目的number_1
和number_2
的乘积。
按天差异过滤:
from datetime import timedelta
result = MyModel.objects.all().annotate(
delta=F('date_2') - F('date_1')
).filter(delta__gte=timedelta(days=10))
现在,result
中的项目来自MyModel
,date_2
比date_1
早10天或更多天。这些项目有一个名为delta
的新列,区别于此。
另一种情况:
我们甚至可以使用F()
表达式对带注释的列进行算术运算,如下所示:
result = MyModel.objects.all()
.annotate(sum_1=Sum('number_1'))
.annotate(sum_2=Sum('number_2'))
.annotate(sum_diff=F('sum_2') - F('sum_1'))