我们可以使用 Django "F" 表达式修改 Django 查询集中的值吗?查询优化

can we modify value in django queryset using Django "F" expression . Query optimisation

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, connection,
            template="EXTRACT(EPOCH FROM %(expressions)s)",
            **extra_context)

    def as_mysql(self, compiler, connection, **extra_context):
        return super().as_sql(
            compiler, connection,
            template="UNIX_TIMESTAMP(%(expressions)s)",
            **extra_context)

    def as_sqlite(self, compiler, connection, **extra_context):
        return super().as_sql(
            compiler, connection,
            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
)