I am trying to add a custom "Upcoming" filter to the Django Admin DateFieldListFilter. It's really simple, just selecting dates after today. Building on this thread i was able to extend Django's standard DateFieldListFilter into my own custom one as follows :
class MyDateTimeFilter(DateFieldListFilter):
def __init__(self, *args, **kwargs):
super(MyDateTimeFilter, self).__init__(*args, **kwargs)
today = datetime.now()
self.links += (('Upcoming'), {self.lookup_kwarg_since: today.strftime('%d %B %Y')}),
It correctly displays "Upcoming" at the bottom of my filters, but clicking does not actualy filter the results. I do not know what's wrong with my syntax and I have tried many alternatives...
Your help is very much appreciated!
PS: I am using Python 3.5.2 and Django 2.0.6
Without jumping straight into this one, I have done exactly what you needed for a previous project:
In filters.py
:
import datetime
from django.contrib.admin.filters import DateFieldListFilter
from django.utils.translation import gettext_lazy as _
class MyDateTimeFilter(DateFieldListFilter):
def __init__(self, *args, **kwargs):
super(MyDateTimeFilter, self).__init__(*args, **kwargs)
now = timezone.now()
# When time zone support is enabled, convert "now" to the user's time
# zone so Django's definition of "Today" matches what the user expects.
if timezone.is_aware(now):
now = timezone.localtime(now)
today = now.date()
self.links += ((
(_('Upcoming'), {
self.lookup_kwarg_since: str(today),
self.lookup_kwarg_until: str(today + datetime.timedelta(days=7)),
}),
))
You want to add a few declarations to be used later (e.g., today = now.date()
) and then you want to use the self.lookup_kwarg_until
keyword argument, and have some time range as your lookup until date (for ease, I have used today + datetime.timedelta(days=7)
, but you could quite easily configure this to whatever timespan you need.
Then you'd need something like this in admin.py
:
from django.contrib import admin
from filters import MyDateTimeFilter
class PostAdmin(admin.ModelAdmin):
list_filter = (
('published_at', MyDateTimeFilter()),
)
Disclaimer: this worked on Python 3.7, Django 2.0*. Fingers crossed this works for you!