Django offers a few fields that are exclusive to Postgres. I recently had to use DateRangeField which is an interesting alternative to doing the usual
If you’re using Django Rest Framework, you are probably familiar with django-filters. It’s a generic system for filtering Django QuerySets, though I’ve mostly used it in combination with DRF.
Tested with following versions:
- Django 1.11 (confident this will work with Django 2.1)
- django-filters 2.0.0 (won’t work with previous versions, because 2.0 release includes a reworked version of RangeWidget)
Ranges are composed of lower and upper bounds that operate as a whole value. I want to be able to specify both bounds when filtering and get the objects that satisfy these exact values. By default, Django stores
DateRangeField in its canonical form
[) - lower inclusive and upper exclusive. In this case, I’m fine to specify and filter the bounds only in their canonical form. But it should be fairly easy to extend this to support different range types.
From the filters list I spot
DateRangeFilter defines a list of choices to select from (like today, yesterday past week, etc), not exactly what I’m looking for.
DateFromToRangeFilter looks more appealing, as it allows filtering using the
_before suffixes. It will conveniently convert the passed strings to
DateField and do
lte lookups on the field. Still not exactly what I need.
Show me the code
In your app:
Let’s start from the bottom -
DateExactRangeFilter. Since we are doing a regular lookup, we are inheriting directly from
field_class here is important, as it converts the raw values to a format and type we need, in this case
DateRange composed of start and end dates. The
DateExactRangeWidget lists the available suffixes.
Now you can do this
/api/events?event_dates_start=2018-08-07&event_dates_end=2018-08-12 to filter all events that start and end exactly on these dates.
This solution is not ideal, because none of this documented. Django-filters doesn’t provide a guide on how to extend existing classes to add your own filters, fields or widgets. The details of how these objects behave might change with time, hence use this at your own risk.