#django-2.0
#django-2.0
Вопрос:
now = datetime.utcnow().replace(tzinfo=utc)
.annotate(
age=F(int((now - 'ended_at').total_seconds() / (60 * 60)))
Я хочу добавить логику, подобную приведенной выше, в запрос Django.
по сути, я хочу вычислить «возраст», который является причиной необходимости выполнения операции ORM.
наличие больших данных и их время, если я выполняю эту операцию с помощью цикла for.
Ответ №1:
Сначала определите a 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
)
Комментарии:
1. Я использую mysql
2. as_mysql используется для MySQL