【问题标题】:Django query : "datetime + delta" as an expressionDjango 查询:“datetime + delta”作为表达式
【发布时间】:2013-07-15 03:41:58
【问题描述】:

嗯,我的问题有点如下:

假设我有下一个模型,这是一个简单的案例:

class Period(models.Model):
    name = CharField(... field specs here ...)
    start_date = DateTimeField(... field specs here ...)
    duration = ... don't know what field should i use but this has to hold a delta ...

我想在 django 查询中检索 (start_date + duration)

我怎样才能得到它?

【问题讨论】:

    标签: python sql django datetime timedelta


    【解决方案1】:

    我认为您的快速回答是从您现在的日期时间中减去而不是从模型日期时间中添加,如下所示:

    .filter(start_date__lte=datetime.now()-timedelta(days=duration))
    

    【讨论】:

    • 谢谢,这对我有帮助。这样的菜鸟问题我做了xDDD。但是......如果我需要与另一个领域进行比较怎么办?例如.filter(start_date__lte=F('another_datetime_field')-timedelta(...)) 是否允许? 已编辑:对不起,我需要从模型中获取持续时间。这意味着:duration 和 start_date 都是特定于实例的。
    • 我认为没有办法通过 ORM 在单个查询中做到这一点。我认为您的选择是接受使用两个查询或使用extra 子句将适合您的数据库后端的日期算术放入约束中。
    • 是的...我会试试我昨天想的“.extra(where=...)”
    【解决方案2】:

    由于您的过滤器依赖于同一模型的两个属性,您需要为duration 部分使用F() expression,同时将其与某种timedelta 结合使用。目前 Django ORM 不支持。

    不过,您可以使用extra() 呼叫。这种方法的缺点是它与数据库无关。这是针对 PostgreSQL 的:

    Period.objects.extra(
        where=["start_date + duration * INTERVAL '1 day' < %s"],
        params=[datetime.now()]
    )
    

    假设您的持续时间以天为单位。如果不是,请相应调整。

    【讨论】:

    • 对于不同的数据库是否有等效的方法?
    【解决方案3】:

    您可能希望避免在 Django ORM 查询中使用 extra,因此您可以应用下一个解决方法:

    1)添加计算字段并在每个模型的保存时更新它(您应该根据您的逻辑调整保存逻辑)

    class Period(models.Model):
        name = CharField()
        start_date = DateTimeField()
        duration = IntegerField(help_text='hours')
        end_date = DateTimeField()
    
    def save(self, *args, **kwargs):
        self.end_date = self.start_date + datetime.timedelta(days=self.duration)
        super(Period, self).save(*args, **kwargs)
    

    2) 然后在查询中使用计算字段:

    finished = Period.objects.filter(end_date__lt=datetime.datetime.now())
    

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 2016-11-09
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多