tags:

views:

241

answers:

3

I'm trying to fetch all expired objects for a model in my Django application.

The model looks like this:

MyModel(models.Model):
    owner = models.ForeignKey(User)
    last_check = models.DateTimeField(blank=True, null=True)
    interval = models.IntegerField(default=1800)

I need to fetch all matching objects where last_check is earlier than now minus the check interval in order to determine if the object should be checked again.

No problem if I use a static interval:

time_diff = datetime.now() - timedelta(seconds=1800)
MyModel.object.filter(last_check__lte=time_diff)

But when the interval is on the model itself I can't figure out how to do it. This is what I tried:

objects_to_check = MyModel.objects.filter(
                                        last_check__isnull=False
                                    ).filter(
                                        last_check__lte=datetime.now() - timedelta(seconds=F('interval'))
                                    )

But that didn't work at all, only gave me the following error

unsupported type for timedelta seconds component: F

Any idea how to solve this?

+2  A: 

Hm... I am not sure if you can modify the value of the field being looked up. Database would still need to retrieve the value first, apply the function timedelta on it and than do a comparison.

I think you might need to rethink your architecture... but I might be wrong. Maybe instead of storing last_check, store the expired property, that you can check directly:

MyModel.objects.filter(expired__lte=current_date)

and then when updating the model:

def save(self):
    self.expired = datetime.now() + self.interval;

or something like that.

drozzy
Thank you for your input. This was the solution I ended up with.
Daniel Johansson
+1  A: 

F object stands for a reference to model field in the SQL query, so you cannot initialize a Python object with it. You can write database-specific query using extra method or just filter them on Python level:

filter(lambda x: x.last_check <= datetime.now() - timedelta(seconds = x.interval), MyModel.objects.all())
Dmitry Risenberg
A: 

support for this kind of queries is in the works: http://code.djangoproject.com/ticket/10154

turingmachine