Django ORM : Filter on timedelta of Datetime fields

标签 django django-orm django-aggregation

我试图根据两个 DateTimeField 的时差来获取帖子例如,发布后不到 10 分钟就被删除的帖子。

class Post(models.Model):
    ...
    time_posted = models.DateTimeField()
    time_deleted = models.DateTimeField(blank=True, null=True)
有了上面的模型,我试过了;
from datetime import timedelta

Post.objects.exclude(deleted__isnull=True).annotate(
    delta=F('time_deleted') - F('time_posted')
).filter(delta__lt=timedelta(minutes=10))
并得到了一个 TypeError: expected string or buffer .然后我想这可能是类型的变化(DateTime 对象产生了 Time 对象)所以我用 ExpressionWrapper 试了一下。 :
Post.objects.exclude(deleted__isnull=True).annotate(
    delta=models.ExpressionWrapper(
        F('time_deleted') - F('time_posted'), 
        output_field=models.TimeField())
    ).filter(delta__gt=timedelta(minutes=10))
但这也导致了同样的异常。
任何帮助深表感谢。
编辑
根据@ivan 的建议,我尝试了 DurationField()反而。我不再遇到异常,但增量始终是 0 .
>>> post = Post.objects.exclude(deleted__isnull=True).annotate(
        delta=ExpressionWrapper(F('deleted') - F('time'), 
        output_field=DurationField())
    ).first()
>>> post.time_posted
datetime.datetime(2015, 8, 24, 13, 26, 50, 857326, tzinfo=<UTC>)
>>> post.time_deleted
datetime.datetime(2015, 8, 24, 13, 27, 30, 521569, tzinfo=<UTC>)
>>> post.delta
datetime.timedelta(0)

最佳答案

output_field kwarg 应该是 DurationField 相反,因为它存储 datetime.timedelta在 Django 中,而 TimeField专卖店 datetime.time .

不过有一个警告:

Arithmetic with DurationField works in most cases. However on all databases other than PostgreSQL, comparing the value of a DurationField to arithmetic on DateTimeField instances will not work as expected.



在 SQLite 后端 DurationFieldbigint 表示存储微秒:
class DatabaseWrapper(BaseDatabaseWrapper):
    vendor = 'sqlite'
    # ...
    data_types = {
        # ...
        'DecimalField': 'decimal',
        'DurationField': 'bigint',
        'FileField': 'varchar(%(max_length)s)',
        # ...
    }

因此,因为您使用的是 SQLite,所以您实际上需要 delta以微秒为单位的值。见 this answer对于 Func这样做。

关于Django ORM : Filter on timedelta of Datetime fields,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32720441/

相关文章:

django - 可以更改Django信号的顺序吗?

django - 如何在 Django 中重命名 values() 中的项目?

django - 在 Django 模型的属性中使用聚合

python - 如何评估模板中两个变量的串联?

Django 。如何获取 session 并将其保存为外键。

python - Django:每个外键返回一个过滤对象

django - 如何使用基于类的 View 按 Django 中相关字段的总和进行排序?

python - Django 注释外键的外键计数

python - 是否可以分别对多个列进行 GROUP BY 并使用 django ORM 通过其他列聚合它们中的每一个?

Python Django : Time Zone Conversion