как использовать __year и __in в одном запросе?

Итак, вот что я пытаюсь сделать.
У меня есть список с годами внутри, например, years = [2002, 2003, 2004]
и у меня есть SomethingModel с DateField

Я хочу сделать запрос, который вернет мне все объекты, принадлежащие этому году:

Я знаю эту работу:

 SomethingModel.objects.filter(date__year=2003) 
 SomethingModel.objects.filter(date__in=[list with dates])

Итак, я пробовал это:

SomethingModel.objects.filter(date__year__in=years)

но это возвращает мне эту ошибку:

FieldError: Join on field 'date' not permitted. Did you misspell 'year' for the lookup type?

Кто-нибудь знает, как это сделать? Напрямую..

Спасибо!


person psoares    schedule 22.06.2011    source источник


Ответы (4)


Вы не сможете, если посмотрите документацию по набору запросов.

Entry.objects.filter(pub_date__year=2005)

становится эквивалентом SQL:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31 23:59:59.999999';

Таким образом, вы не можете концептуально смешивать __in и __date. В любом случае вы не можете смешивать суффиксы, так как первый «суффикс» будет интерпретирован как несуществующая связь.

Вам нужно будет использовать фильтр «меньше чем» и фильтр «больше чем» или, если список не является непрерывным, дополнительное поле «где», например:

SomethingModel.objects.extra(where=["YEAR(date) IN (" + ",".join([str(x) for x in [2003, 2008, 2010]]) + ")"])
person Rob Osborne    schedule 22.06.2011
comment
именно то, что я хотел! Спасибо :) Хотя это работает только с квадратными скобками: SomethingModel.objects.extra(where=[YEAR(date) IN (2002, 2006)]) - person psoares; 22.06.2011
comment
хотя это не работает, если я пытаюсь заменить (2002, 2006, 2009) годами. кажется, он не принимает имя переменной.. - person psoares; 22.06.2011
comment
конечно, я просто сказал, потому что это может быть полезно для других людей! Спасибо, это работает :) - person psoares; 22.06.2011
comment
возможно, это также сработает: Entry.objects.extra(where=['headline=%s'], params=['Lennon']) Я собирался попробовать это, прежде чем вы обновили свой ответ: P - person psoares; 22.06.2011

Можешь попробовать,

SomethingModel.objects.filter(date__year=[year for year in years])
person vim    schedule 22.06.2011
comment
Я уже пробовал это .. дает ту же ошибку, так как это не int - person psoares; 22.06.2011

Если ваш список лет всегда последователен, вы можете сделать

SomethingModel.objects.filter(date__year__gte=years[0], date__year__lte=years[-1])
person Gert Steyn    schedule 23.06.2011
comment
нет, список лет выбирает пользователь. но все равно спасибо - person psoares; 24.06.2011

Вы можете использовать: SomethingModel.objects.filter(date__range=(date_1, date_2)

person Efrin    schedule 17.04.2014