如何在django

时间:2017-08-09 14:24:13

标签: python django

序言

这是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()

如何在此模型的字段之间执行算术运算?

例如,我该如何找到:

  • MyModel对象的number_1number_2的乘积?
  • 如何过滤date_2date_1早10天或以上的项目?

1 个答案:

答案 0 :(得分:8)

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中的项目来自MyModeldate_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'))