我有一个简单的模型来描述任务和执行任务之间的时间段:
class Task(models.Model):
last_check_timestamp = models.DateTimeField(blank=True, null=True, db_index=True)
class TaskSchedule(models.Model):
task = models.OneToOneField(Task, blank=False, null=False, related_name='schedule')
interval_seconds = models.IntegerField(blank=False, null=False)
我希望能够使用Django的ORM查询哪些任务是新鲜的,哪些是陈旧的,这意味着那些将根据他们的日程安排运行。
我正在为没有ORM的特定记录计算这个:
import datetime
task = Task.objects.get(id=123)
fresh = task.last_check_timestamp is not None and datetime.datetime.now() < (task.last_check_timestamp + datetime.timedelta(seconds=task.schedule.interval_seconds))
我如何使用Django的ORM进行等效操作,这样我就可以一次查询所有新鲜/陈旧的任务?
e.g。这显然不起作用,但是像:
Tasks.objects.filter(Q(last_check_timestamp__isnull=True) || Q(last_check_timestamp + datetime.timedelta(seconds=schedule__interval_seconds)))
答案 0 :(得分:3)
我最近不得不做类似的查询。我希望使用F()
对象来做这件事,但我不认为这是可能的,因为timedelta依赖于db列(如果schedule_interval_seconds
是常量则可能)。
最后,我使用带有extra()
的ORM进行了查询,并为where子句编写了SQL。
sql = "DATE_ADD(last_check_timestamp, INTERVAL schedule.interval_seconds SECOND) < DATE(NOW())"
Tasks.objects.filter(Q(last_check_timestamp__isnull=True) || Q(last_check_timestamp + datetime.timedelta(seconds=schedule__interval_seconds)))
tasks = Task.object.select_related('schedule').extra(where=[sql,]
这使用DATE_ADD
函数(MySQL docs)。您可能需要针对不同风格的SQL进行调整。 select_related
是必需的,以便Django连接到计划表。
上面没有选择last_check_timestamp
为空的任务。我认为您不能使用extra()
和Q
对象的组合,但您可以扩展SQL语句。
sql = """last_check_timestamp is NULL or DATE_ADD(last_check_timestamp, INTERVAL schedule.interval_seconds SECOND) < DATE(NOW())"""