Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making queries using F() and timedelta at django

Tags:

orm

django

I have the following model:

class Process(models.Model):
  title = models.Charfield(max_length=255)
  date_up = models.DateTimeField(auto_now_add=True)
  days_activation = models.PositiveSmallIntegerField(default=0)

Now I need to query for all Process objects that have expired, according to their value of days_activation.

I tried

from datetime import datetime, timedelta

Process.objects.filter(date_up__lte=datetime.now()-timedelta(days=F('days_activation')))

and received the following error message:

TypeError: unsupported type for timedelta days component: F

I can of course do it in Python:

filter (lambda x: x.date_up<=datetime.now() - timedelta(days=x.days_activation), 
        Process.objects.all ()), 

but I really need to produce a django.db.models.query.QuerySet.

like image 391
rmaceissoft Avatar asked May 28 '11 00:05

rmaceissoft


1 Answers

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.

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

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

like image 154
Lutz Prechelt Avatar answered Nov 07 '22 03:11

Lutz Prechelt