'How to filter in django by greater than or less than dates?
I'm a little confused with the documentation on Django Rest Framework. I have read it several times but I cannot makes sense of it. Maybe I'm not smart enough, I do not know, but I'm trying to create a filter in an Endpoint that let me consult information according to dates, like
GET /my-endpoint/?created_at__lte=2020-01-01 // get items created in a date less than 2020-01-01
GET /my-endpoint/?created_at__gte=2020-01-01 // get items created in a date greater than 2020-01-01
I created a filter class
class MyEndpointFilter(django_filters.rest_framework.FilterSet):
created_at_gte = IsoDateTimeFilter(field_name="created_at", lookup_expr='gte')
created_at_lte = IsoDateTimeFilter(field_name='created_at', lookup_expr='lte')
updated_at_gte = IsoDateTimeFilter(field_name='updated_at', lookup_expr='gte')
updated_at_lte = IsoDateTimeFilter(field_name='updated_at', lookup_expr='lte')
class Meta:
model = MyEndpointModel
fields = (
'created_at',
'updated_at',
)
And a class view
class MyEndpointViewSet(viewsets.ReadOnlyModelViewSet):
filter_backends = (
django_filters.rest_framework.DjangoFilterBackend, OrderingFilter
)
filterset_class = MyEndpointFilter
filterset_fields = {'created_at': ['gte', 'lte'], 'updated_at': ['gte', 'lte']} # I also tried without this line
queryset = LogClaimAction.objects.all()
serializer_class = MyEndPointSerializer
But still, the filter doesn't work. Can someone point me to the mistake I am making?
Solution 1:[1]
You can use django_filters.FilterSet
instead of django_filters.rest_framework.FilterSet
in your filterset_class
and make your filterset_fields a list instead of dict.
import django_filters
...
class MyEndpointFilter(django_filters.FilterSet):
created_at_gte = IsoDateTimeFilter(field_name="created_at", lookup_expr='gte')
created_at_lte = IsoDateTimeFilter(field_name='created_at', lookup_expr='lte')
updated_at_gte = IsoDateTimeFilter(field_name='updated_at', lookup_expr='gte')
updated_at_lte = IsoDateTimeFilter(field_name='updated_at', lookup_expr='lte')
class Meta:
model = MyEndpointModel
fields = '__all__'
from django_filters.rest_framework import DjangoFilterBackend, OrderingFilter
...
class MyEndpointViewSet(viewsets.ReadOnlyModelViewSet):
queryset = LogClaimAction.objects.all()
serializer_class = MyEndPointSerializer
filter_backends = (DjangoFilterBackend, OrderingFilter)
filterset_class = MyEndpointFilter
filterset_fields = ['created_at_gte', 'created_at_lte', 'updated_at_gte', 'updated_at_lte']
Testing
GET /my-endpoint/?created_at_lte=2020-02-02
GET /my-endpoint/?created_at_gte=2020-01-01
GET /my-endpoint/?created_at_lte=2020-02-02&created_at_gte=2020-01-01
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ged Flod |