You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Django ORM获取与上一行至少间隔指定时长的所有数据行?

问题:筛选Django模型中时间间隔≥指定秒数的记录

我的Django模型定义如下:

class MyModel(Model):
    timestamp = models.DateTimeField(auto_now=True)
    ...

我需要从MyModel中筛选出与上一条记录时间间隔至少为指定秒数的数据行。数据通常每30秒新增一条,但我要保留间隔≥30秒的记录,同时还要限制记录在指定日期范围内(这部分功能已实现)。

我尝试了多种方案,以下是最接近目标的一种:

queryset = MyModel.objects.annotate(
    time_diff=F("timestamp") - Window(
        expression=Lag("timestamp"),
        order_by=(F("timestamp"),)
    )
)

这个方案不会直接报错,time_diff字段也能正常生成(比如queryset.last().time_diff会返回timedelta类型的值),但当我尝试对time_diff进行filter筛选时,会抛出错误:NotSupportError: Window is disallowed in the filter clause。

我还试过另外两种无效方案:

方案二:

start_date = datetime(...)
end_date = datetime(...)
time_interval = ...  # 总秒数

time_diff_window = Window(
    expression=Lag('timestamp'),
    order_by=F('timestamp').asc(),
)

queryset = MyModel.objects.filter(
    timestamp__range=(start_date, end_date),
).annotate(
    time_diff=Extract('timestamp', 'epoch') - Extract('lagged_timestamp', 'epoch'),
    lagged_timestamp=Lag('timestamp', default=start_date, over=time_diff_window),
).filter(
    time_diff__gte=time_interval,
).order_by('timestamp')

方案三:

window = Window(expression=Lag("timestamp"), order_by=F('timestamp').asc())
lagged_timestamp = Lag("timestamp", default=Value(timedelta(seconds=0), output_field=DurationField()), over=window,)

# 计算当前行与上一行的时间差
time_diff = Coalesce(F("timestamp") - lagged_timestamp, Value(timedelta(seconds=0), output_field=DurationField()))

# 筛选时间差大于指定间隔的记录
readings = MyModel.objects.annotate(
    time_diff=time_diff,
).filter(
    time_diff__gte=timedelta(seconds=time_interval),
    timestamp__range=(start_date, end_date),
).order_by("timestamp")

我知道可以用Python代码实现这个筛选逻辑,但更希望通过Django ORM完成,让数据库来承担计算压力。

内容的提问来源于stack exchange,提问作者Dakota Horstman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:53:26