How can I use the F() object to do this with the Django ORM?

后端 未结 2 2105
旧巷少年郎
旧巷少年郎 2021-02-09 20:56

I encountered a model like this:

class Task(models.Model):
    timespan = models.IntegerField(null=True, blank=True)

class Todo(models.Model):
    limitdate = m         


        
2条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-09 21:39

    The main issue is that DB does not support date + integer and its hard to write ORM query to date + integer::interval, for PostgreSQL for example, where integer is the value of the task_timespan column, in days count.

    However, as
    limitdate <= today + task__timespan equals to
    limitdate - today <= task__timespan

    We could transform the query to

    Todo.objects.filter(task__timespan__gte=F('limitdate') - today).distinct()

    thus the SQL becomes something like integer >= date - date, that should work in PostgreSQL because date - date outputs interval which could be compared w/ integer days count.

    In other DBs such as SqLite, it's complicated because dates need to be cast w/ julianday() at first...and I think you need to play w/ extra() or even raw() to get the correct SQL.

    Also, as Chris Pratt suggests, if you could use timestamp in all relative fields, the query task might become easier because of less limited add and subtract operations.

    P.S. I don't have env to verify it now, you could try it first.

提交回复
热议问题