问题描述
Now = datetime.utcNow().replace(tzinfo=utc)
.annotate(
age=F(int((Now - 'ended_at').total_seconds() / (60 * 60)))
我想在 Django 查询中添加上述逻辑。 基本上我想计算“年龄”,这是需要执行操作 ORM 的原因。 如果我使用 for 循环执行此操作,则数据量很大且需要时间。
解决方法
首先定义一个 Func
来提取自 UNIX 纪元以来的秒数。
from django.db.models import Func,IntegerField
class UnixTime (Func):
"""
Extract the number of seconds since January 1,1970.
"""
arity = 1
output_field = IntegerField()
# for PostgreSQL
def as_sql(self,compiler,connection,**extra_context):
return super().as_sql(
compiler,template="EXTRACT(EPOCH FROM %(expressions)s)",**extra_context)
def as_mysql(self,template="UNIX_TIMESTAMP(%(expressions)s)",**extra_context)
def as_sqlite(self,template="CAST(strftime('%%%%s',%(expressions)s) AS INTEGER)",**extra_context)
然后进行这样的查询:
from django.db.models import F
from django.db.models.functions import Now
YourObject.objects.annotate(
age=(UnixTime(Now()) - UnixTime(F('ended_at'))) / 3600
)