Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-rest-framework filter by date=None

I am using django-rest-framework with django-filter. I need to retrieve a list of Widgets where the date property is None, but no matter what query I have tried, I am getting either empty responses or full, unfiltered responses.

Here's how I have defined the viewset and filterset.

class WidgetFilter(django_filters.FilterSet):
    date = django_filters.DateTimeFilter(name='date', lookup_type='exact')
    no_date = django_filters.DateTimefilter(name='date', lookup_type='isnull')
    class Meta:
        model = Widget
        fields = ['date',]

class WidgetSet(viewsets.ModelViewSet):
    model = Widget
    filter_class = WidgetFilter

The following queries result in empty [] responses:

?date=None
?date=0
?date=NULL
?date=False
?date=2012-05-24T11:20:06Z  # a known and correct date

The following queries result in all objects being returned:

?date=
?no_date=True
?no_date=False
?no_date=1
?no_date=0

Any help is very much appreciated! I have been unable to find any information on using dates (or passing None as a filter value) with django-filter specifically via django-rest-framework.


In case there is no more elegant way, here is how I bodged my workaround, but I'd still like to know of a solution that uses django-filter, if one exists.

class WidgetSet(viewsets.ModelViewSet):
    model = Widget

    def get_queryset(self):
        if 'no_date' in self.request.QUERY_PARAMS:
            return self.model.objects.filter(date=None)
        return self.model.objects.all()
like image 910
tobygriffin Avatar asked Feb 03 '14 04:02

tobygriffin


3 Answers

Specifying isnull directly in the filter's name argument as 'date__isnull' seems to be working for me with Django REST Framework 3.1.3.

class WidgetFilter(django_filters.FilterSet):
    date = django_filters.DateTimeFilter(name='date')
    no_date = django_filters.BooleanFilter(name='date__isnull')
    class Meta:
        model = Widget
        fields = []
like image 85
Matmas Avatar answered Nov 13 '22 14:11

Matmas


I ran into a similar situation today, and it appears as if out of the box django rest framework* supports this filter as:

~/your_endpoint/?date__isnull=True

This matches up with how the the equivalent ORM query would look. If that's ugly, you can use the docs example to transform that query parameter to something else without having to override get_queryset

  • I'm using 2.4.3, but I don't believe this is a new thing
like image 38
Rob Dennis Avatar answered Nov 13 '22 14:11

Rob Dennis


Running django-filter==1.0.4 and djangorestframework==3.6.3.

The correct answer didn't work because module paths have changed in django-filter (BooleanFilter moved to django_filters.rest_framework).

And the __isnull didn't work either, I had to use lookup_expr:

from django_filters import rest_framework as filters


class WidgetFilter(filters.FilterSet):
    no_date = filters.BooleanFilter(name='date', lookup_expr='isnull')

    class Meta:

        model = Widget
        fields = ( 'date')

Got the answer from https://github.com/carltongibson/django-filter/issues/743

Now I can filter by "no date" using http://localhost:8000/widgets/?no_date=True

like image 41
Sebastien DA ROCHA Avatar answered Nov 13 '22 14:11

Sebastien DA ROCHA