Django ORM фильтрация с помощью выражения по нескольким полям
Я пытаюсь использовать фильтр Django ORM для получения записей Announcement с датами объявления (announcement_dates), которые позже текущей даты - поле "expire_in_days" - т.е. получить объявления, срок действия которых еще не истек.
Вот SQL представление того, что я пытаюсь сделать с помощью ORM:
select *
from announcement
where message_date > current_date - expire_in_days;
Я должен иметь возможность получать все записи и фильтровать их извне, но я пытаюсь узнать, как это сделать с помощью Django.
Вот моя модель
class Announcement(models.Model):
message = models.TextField("announcement message")
message_date = models.DateField("Announcement date")
expire_in_days = models.PositiveIntegerField("Number of days before announcement expires")
def __str__(self) -> str:
return '(message: %s, message_date: %s, expire_in_days: %s)' % (self.message, self.message_date, self.expire_in_days)
Вот что я пробовал, но это не сработало:
In [1]: from events.models import Announcement
In [2]: from datetime import date, timedelta
In [3]: from django.db.models import F
In [4]: date.today()
Out[4]: datetime.date(2022, 5, 29)
In [5]: date.today() - timedelta(days=2)
Out[5]: datetime.date(2022, 5, 27)
In [6]: Announcement.objects.all()
Out[6]: <QuerySet [<Announcement: (message: There is a surprise coming up!, message_date: 2022-05-27, expire_in_days: 1)>]>"
In [7]: Announcement.objects.filter(message_date__gt = (date.today() - timedelta(days = F('expire_in_days'))))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [7], in <cell line: 1>()
----> 1 Announcement.objects.filter(message_date__gt = (date.today() - timedelta(days = F('expire_in_days'))))
TypeError: unsupported type for timedelta days component: F
Я предполагал, что могу просто сделать это, но по какой-то причине это даже не привело к сбою, но и не отфильтровало запись, как я ожидал
In [8]: Announcement.objects.filter(message_date__gt = date.today() - F('expire_in_days'))
Out[8]: <QuerySet [<Announcement: (message: There is a surprise coming up!, message_date: 2022-05-27, expire_in_days: 1)>]>
Announcement.objects.filter(
message_date__gt=date.today() - timedelta(days=1)*F('expire_in_days')
)
Это должно работать с PostgreSQL