问题
Well, my question is a bit as follows:
Suppose I have the next model, this is a simple case:
class Period(models.Model):
name = CharField(... field specs here ...)
start_date = DateTimeField(... field specs here ...)
duration = ... don't know what field should i use but this has to hold a delta ...
I would like to retrieve objects where (start_date + duration) < now in a django query (i know i can, in python, test like my_date_time + a_time_delta < datetime.now(), but this is not the case ... i need it as part of the query).
How can i get it?
回答1:
I think your quick answer is to subtract from your now datetime versus add from the model datetime like this:
.filter(start_date__lte=datetime.now()-timedelta(days=duration))
回答2:
As your filter depends of two attributes of the same model, you would need to use an F() expression
for the duration
part and at the same time combine it with some sort of timedelta
. That's not supported in the Django ORM at the moment.
You can use an extra()
call, though. The disadvantage of this approach is that it is not database-agnostic. This is for PostgreSQL:
Period.objects.extra(
where=["start_date + duration * INTERVAL '1 day' < %s"],
params=[datetime.now()]
)
assuming that your duration is in days. If not, adjust accordingly.
回答3:
You may want to avoid using extra
in your Django ORM queries, so you can apply next workaround:
1) add calculated field and update it on each model's save (you should adjust save logic according to your logic)
class Period(models.Model):
name = CharField()
start_date = DateTimeField()
duration = IntegerField(help_text='hours')
end_date = DateTimeField()
def save(self, *args, **kwargs):
self.end_date = self.start_date + datetime.timedelta(days=self.duration)
super(Period, self).save(*args, **kwargs)
2) then use calculated field in your queries:
finished = Period.objects.filter(end_date__lt=datetime.datetime.now())
来源:https://stackoverflow.com/questions/17685355/django-query-datetime-delta-as-an-expression