在 Django 中使用 F() 和 timedelta 进行查询 [英] Making queries using F() and timedelta at django
问题描述
我有以下模型:
class Process(models.Model):
title = models.Charfield(max_length=255)
date_up = models.DateTimeField(auto_now_add=True)
days_activation = models.PositiveSmallIntegerField(default=0)
现在我需要根据 days_activation
的值查询所有已过期的 Process
对象.
Now I need to query for all Process
objects that have expired, according to their value of days_activation
.
我试过了
from datetime import datetime, timedelta
Process.objects.filter(date_up__lte=datetime.now()-timedelta(days=F('days_activation')))
并收到以下错误消息:
TypeError: timedelta days 组件不支持的类型:F
我当然可以用 Python 来做:
I can of course do it in Python:
filter (lambda x: x.date_up<=datetime.now() - timedelta(days=x.days_activation),
Process.objects.all ()),
但我真的需要生成一个 django.db.models.query.QuerySet
.
but I really need to produce a django.db.models.query.QuerySet
.
推荐答案
7 days == 1 day * 7
F
是深黑色的 Django 魔法和遇到它的对象必须属于相应的魔法阵才能处理.
7 days == 1 day * 7
F
is deep-black Django magic and the objects that encounter it
must belong to the appropriate magical circles to handle it.
在您的情况下,django.db.models.query.filter
知道 F
,但 datetime.timedelta
不知道.因此,您需要将 F
保留在 timedelta
参数列表之外.幸运的是,F
支持timedelta * int
的乘法,所以以下可以工作:
In your case, django.db.models.query.filter
knows about F
, but datetime.timedelta
does not.
Therefore, you need to keep the F
out of the timedelta
argument list.
Fortunately, multiplication of timedelta * int
is supported by F
,
so the following can work:
Process.objects.filter(date_up__lte=datetime.now()-timedelta(days=1)*F('days_activation'))
事实证明,这个将适用于 PostgreSQL,但不适用于 SQlite(对于 timedelta
,Django 1.11 仅支持 +
和 -
,可能是因为相应的 SQLite 限制).
As it turns out, this will work with PostgreSQL, but will not work with SQlite (for which Django 1.11 only supports +
and -
for timedelta
,
perhaps because of a corresponding SQlite limitation).
这篇关于在 Django 中使用 F() 和 timedelta 进行查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!