Using
django-filter==2.2.0
djangorestframework==3.10.3
Windows 10
DB: PostgreSQL 11.6
I wanted to filter by date on my submitted_at DateTime field so I made this
from django_filters import rest_framework
class DateRangeFilter(rest_framework.FilterSet):
date_from = rest_framework.DateTimeFilter(
field_name="submitted_at", lookup_expr='gte')
date_to = rest_framework.DateTimeFilter(
field_name="submitted_at", lookup_expr='lte')
class Meta:
fields = ['date_from', 'date_to']
It works fine for date_from as expected but for date_to it doesn't return the date exclusively as it supposes to do
for example:
https://
expected data
"line_chart_data": [
{
"submitted_at": "2019-01-05T18:10:49.811259+02:00",
"answers": [
{
"question": 2,
"choice": 4
},
{
"question": 3,
"choice": 4
},
{
"question": 4,
"choice": 4
}
]
},
{
"submitted_at": "2019-01-04T18:10:49.809389+02:00",
"answers": [
{
"question": 2,
"choice": 4
},
{
"question": 3,
"choice": 4
},
{
"question": 4,
"choice": 4
}
]
}]
https://
actual data:
"line_chart_data": [
{
"submitted_at": "2019-01-04T18:10:49.809389+02:00",
"answers": [
{
"question": 2,
"choice": 4
},
{
"question": 3,
"choice": 4
},
{
"question": 4,
"choice": 4
}
]
}]
and that's a bit odd, as if something is wrong it should not work at all not only for date_to unless there is some reason
I know I'm giving it only dates but no warning was in the console and everything was just ok
This is not a bug. Change your DateRangeFilter filter to the following so it works like you would expect:
class DateRangeFilter(rest_framework.FilterSet):
date_from = rest_framework.DateTimeFilter(
field_name="submitted_at__date", lookup_expr='gte')
date_to = rest_framework.DateTimeFilter(
field_name="submitted_at__date", lookup_expr='lte')
class Meta:
fields = ['date_from', 'date_to']
Notice the __date
after your field names.
The reason after this is that you need to extract the date
from your DateTimeField
so the filter operation (lte
) can be performed between date
and date
, not between date
and datetime
@dalvtor is correct that you should use the date
transform, however the code should look like:
class DateRangeFilter(FilterSet):
date_from = DateFilter(field_name='submitted_at', lookup_expr='date__gte')
field_name
should always map to the model field name. lookup_expr
should handle lookups & transforms.
Just got bit by the same issue. The workaround @rpkilby suggests does indeed work but it's not intuitive, if you use a DateFilter you certainly would expect the lte comparison is against the date.
Maybe we could at least add this to the documentation of DateFilter if we can't fix it in a good way?
Of course thanks to @rpkilby for his answer it showed me the right way to take, but @bwesen That's what I was talking about!
Just to contribute, I had the same problems with DateFilter and DateFromToRangeFilter today. Turns out I was passing nonexistent dates (For example, sending the day part of the date as 31st when the month only had 30 days). After making sure the day part was according to each month, worked like a breeze.
Most helpful comment
@dalvtor is correct that you should use the
date
transform, however the code should look like:field_name
should always map to the model field name.lookup_expr
should handle lookups & transforms.