我正在检索所有记录,对于5分钟以上的记录,我想显示记录的年龄。
输出应该是这样的(在此示例中,两条记录:1.8.9.1
和2.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')
age
和age2
都可以工作,但是问题是我希望早于5分钟的记录按age
排序,其余按ip
< / p>
因此,如果少于5分钟,我将尝试将age
设置为0
。
如果我直接在PostgreSQL中执行此操作,我将使用以下查询:
select ip, <other fields>,
case when extract('epoch' from now() - "timestamp") > 300
then extract('epoch' from now() - "timestamp")
else 0
end
有没有办法在Django中做到这一点?
答案 0 :(得分:0)
您也可以通过其他方式来完成此操作,这将更快。 搜索所有接口后,获取当前时间,减去该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')
答案 1 :(得分:0)
我知道了:
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/