如何在Django中对模型字段之间执行算术运算

8

序言:

这是一个经常在SO上出现的问题:

它也可以应用于在这里:

我已经在SO文档中编写了一个示例,但由于该文档将于2017年8月8日关闭,因此我将遵循这个广泛赞同和讨论的元回答的建议,并将我的示例转换为自我回答的帖子。

当然,我非常乐意看到任何不同的方法!!


问题:

假设以下模型:

class MyModel(models.Model):
    number_1 = models.IntegerField()
    number_2 = models.IntegerField()
    date_1 = models.DateTimeField()
    date_2 = models.DateTimeField()

我怎样才能在该模型的字段之间执行算术运算?

例如,我怎么找到:

  • MyModel对象的number_1number_2的积?
  • 如何筛选date_2date_1早10天或更多的项目?
2个回答

20

F() 表达式可以用于模型字段之间的算术运算(+-*等),以定义它们之间的代数关系。

F() 对象表示模型字段或注释列的值。它使得可以在不必从数据库中将其提取到 Python 内存中的情况下,就可以引用模型字段的值并对它们执行数据库操作。

接下来解决以下问题:

  • 两个字段的乘积:

    result = MyModel.objects.all().annotate(prod=F('number_1') * F('number_2'))
    

    现在result中的每个项目都有一个额外的列名为“prod”,其中分别包含每个项目的number_1number_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_2date_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')) 
    

6
如有人遇到问题:从django.db.models导入F。 - Mukesh Kumar Singh

0

步骤1:from django.db.models import F

步骤2:from datetime import timedelta

步骤3:您可以在查询集中应用F运算符,如下所示:

MyModel.objects.all().annotate(
         date_diff=F('date_2') - F('date_1')
     ).filter(date_diff__gte=timedelta(days=10)
)

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