2013-05-02 2 views
0

У меня есть таблица событий типа даты + даты.Фильтр Queryset/исключается для дат

Class Event 
    ... 

Class EventDate 
    ... 
    date = models.DateField() 
    event = model.ForeignKey(Event) 

    class Meta: 
     unique_together = ('date', 'event') 

Я пытаюсь найти события, которые больше не происходит, т.е. истек начиная с сегодняшнего дня.

Я попробовал следующее QuerySet:

Event.objects.filter(dates_set__date__lt = 
datetime.date.today()).exclude(dates_set__date__gte = datetime.date.today()) 

Запрос SQL, кажется странным для меня из подзапроса, и это выглядит дорого.

SELECT … FROM "events" INNER JOIN "event_dates" ON ("events"."id" = 
"event_dates"."events_id") WHERE ("event_dates"."date" < '2013-05-02' AND NOT 
(("events"."id" IN (SELECT U1."event_id" FROM "event_dates" U1 WHERE (U1."date" 
>= '2013-05-02' AND U1."event_id" IS NOT NULL)) AND "events"."id" IS NOT NULL))) 

Это правильно?

+0

Зачем вам нужен исключающий? Разве никто не должен работать самостоятельно, либо отфильтровать по датам меньше, чем сегодня, либо исключать даты, которые больше или равны сегодня? – Ngenator

+0

Yup, похоже, что вы правы. Исключает единственный способ не равный? Скажем, у меня есть дополнительное условие, что я хочу «status! = Expired», как я это сделаю без запуска exclude (подзапрос) –

+0

Вы можете с [объектами Q] (https://docs.djangoproject.com/en/ dev/themes/db/queries/# complex-lookups-with-q-objects): '~ Q (status =" expired ")' – Ngenator

ответ

0

Логически, фильтр и исключение одинаковы, поэтому использование того или иного результата должно вернуть желаемые результаты.

Другой способ сделать «исключение» - использовать Q objects, чтобы сделать «нет». Так что если вы хотите, чтобы получить все события с status != "expired" и date < today вы можете использовать

Event.objects.filter(Q(dates_set__date__lt=datetime.date.today()), ~Q(status="expired")) 
+0

Еще раз спасибо. Должно быть, это один из моих ментальных дней. –

Смежные вопросы