Я хотел бы создать фильтр в панели администратора, который будет фильтровать события по году. Я создал список лет, но не знаю, как совместить его с поиском и запросом.
class SearchByYear(admin.SimpleListFilter):
title = _('title')
parameter_name = 'year'
year_list = models.Event.objects.values_list('date', flat=True)
y = [i.year for i in year_list]
print('this is list only with years: ', y)
def lookups(self, request, model_admin):
return (
('year', _('2018')),
('year1', _('2019')),
)
def queryset(self, request, queryset):
if self.value() == 'year':
return queryset.filter(date__year=2018)
if self.value() == 'year1':
return queryset.filter(date__year=2019)






Вы можете передать годы как опции, а затем использовать их при фильтрации:
from django.db.models.functions import ExtractYear
class SearchByYear(admin.SimpleListFilter):
title = _('title')
parameter_name = 'year'
def lookups(self, request, model_admin):
year_list = models.Event.objects.annotate(
y=ExtractYear('date')
).order_by('y').values_list('y', flat=True).distinct()
return [
(str(y), _(str(y))) for y in year_list
]
def queryset(self, request, queryset):
if self.value() is not None:
return queryset.filter(date__year=self.value())
return querysetТаким образом, мы используем lookups для получения разных лет, а затем фильтруем выбранный год с помощью запроса .filter(date__year=self.value()).
Перевод _(str(y)) не является строго необходимым. Это может быть полезно, если годы переведено отличаются в некоторых культурах (например, китайские / японские / римские годы). Но обычно нет проблем с переводом лет, поскольку, если перевод не найден, перевод выполнит "отступать" к исходному значению.
@schwobaseggl: вы правы. Убрал какой-то шум :)
@WillemVanOnsem большое спасибо за вашу работу. Приобрел Cannot use None as a query value в этом месте return queryset.filter(date__year=self.value())
@ user9192656: ага. Да, нам тоже нужно это проверить, см. Редактирование.
Вам вообще нужно приведение
intв последнем операторе фильтра? Они, как правило, очень прочные.