سؤال

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?

هل كانت مفيدة؟

المحلول

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))

نصائح أخرى

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.

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())
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top