【问题标题】:Get record's age in seconds if older than 5 minutes (otherwise 0) in Django (with PostgreSQL database)如果在 Django(使用 PostgreSQL 数据库)中超过 5 分钟(否则为 0),则以秒为单位获取记录的年龄
【发布时间】:2026-02-09 13:20:04
【问题描述】:

我正在检索所有记录,我想显示那些超过 5 分钟的记录的年龄。

输出应该是这样的(在本例中,两条记录:1.8.9.12.7.3.1 超过 5 分钟):

ip       ...  status
---------------------
1.8.9.1  ...  3 hours
2.7.3.1  ...  7 minutes
1.1.1.1  ...  up
1.1.1.2  ...  up
1.1.1.3  ...  up
1.1.1.4  ...  up
1.1.1.5  ...  up

这是我当前的代码:

Interfaces.objects.all()
.annotate(
  age = (datetime.utcnow() - F('timestamp')), # 0:00:08.535704
  age2 = Epoch(datetime.utcnow() - F('timestamp')), # 8.535704
  # age3 = int(Epoch(datetime.utcnow() - F('timestamp'))/300),
  current_time=Value(str(datetime.utcnow()),
                       output_field=null_char_field),
)
.order_by('age','ip')

ageage2 都可以,但问题是我希望超过 5 分钟的记录按 age 排序,其余按 ip 排序

所以我尝试将 age 设置为 0,如果它少于 5 分钟。

如果我直接在 postgresql 中执行,我会使用这个查询:

select ip, <other fields>,
   case when extract('epoch' from now() - "timestamp") > 300
        then extract('epoch' from now() - "timestamp")
        else 0
   end

有没有办法在 django 中做到这一点?

【问题讨论】:

  • 如果您仍然获得“所有记录”,一种选择是简单地使用 all() 并在 Python 中进行任何您想要的排序和组织。

标签: django postgresql django-queryset


【解决方案1】:

你也可以用其他更快的方式来做。 获取当前时间,减去 5 分钟,然后搜索所有接口 其中年龄小于或等于减去的日期。

示例:

current_time = datetime.now()
older_than_five = current_time - datetime.timedelta(minutes=5)

Interfaces.objects.all()
.annotate(
   age=Case(
       When(age__lt=older_than_five, then=Value(0)),
       default=F('age')
   )
)
.order_by('age','ip')

【讨论】:

  • 我需要显示所有记录,而不仅仅是旧记录
  • 我写的查询应该显示所有 5 分钟或更早的记录。 显示所有记录,而不仅仅是旧记录是什么意思?
  • 您的查询显示所有 5 分钟或更早的记录。 “所有记录”是指那些不到 5 分钟的记录。
  • 现在试一试,看看它是否达到了预期的效果。
  • 这有点像我 2 天前所做的。我已经让它工作了。 (见我的回答)但是感谢您的尝试。
【解决方案2】:

我想通了:

Interfaces.objects.all()
.annotate(
   age=Case(
          When(timestamp__lt=datetime.utcnow() - timedelta(minutes=5),
               then=Cast(Epoch(datetime.utcnow() - F('timestamp')),
                         NullIntegerField)),
          default=0,
          output_field=NullIntegerField
   ),
)
.order_by('age','ip')

顺便说一下,我的导入和相关设置:

from django.db.models import  F, Func, Case, When, IntegerField
from django.db.models.functions import Coalesce, Cast

NullIntegerField = IntegerField(null=True)

class Epoch(Func):
    function = 'EXTRACT'
    template = "%(function)s('epoch' from %(expressions)s)"

这个网站最终是最有帮助的:https://micropyramid.com/blog/django-conditional-expression-in-queries/

【讨论】:

    最近更新 更多