Danila Kulakov
Danila Kulakov

Reputation: 1142

Django REST framework range filter

How can I do a range filter for dates and number in Django REST Framework? Other filters (lt, gt etc.) work fine. I tried many variants such as:

import rest_framework_filters as filters

class OrderFilter(filters.FilterSet):
    total_price__range = filters.RangeFilter(name='total_price')
    created_at__range = filters.DateFromToRangeFilter(name='created_at')
    ....
    class Meta:
        model = Order

        fields = {
            'created_at__range': ['__all__'],
            'total_price__range': ['__all__'],
            ...
            }

class OrderViewSet(BaseViewSet, viewsets.ModelViewSet):
    filter_class = OrderFilter
    ....

In the browsable api there are to fields when I click on bottom "Filters", Then url looks like:

/orders/?created_at__range_0=2017-05-22&created_at__range_1=2017-05-22

and it doesn't work. I need something like

/orders/?created_at__range=2017-05-22,2017-05-24

and same with integer:

/orders/?total_price__range=1000,2000

It was described here .

What am I doing wrong?

Upvotes: 8

Views: 8707

Answers (2)

Nayem Jaman Tusher
Nayem Jaman Tusher

Reputation: 1078

For your URL format /orders/?created_at__range=2017-05-22,2017-05-24

for date ranges and /orders/?total_price__range=1000,2000.

for number ranges

import rest_framework_filters as filters

class OrderFilter(filters.FilterSet):
    total_price__range = filters.RangeFilter(field_name='total_price')
    
    # For date range filtering
    created_at__range = filters.DateFromToRangeFilter(field_name='created_at')

    class Meta:
        model = Order
        fields = {
            'created_at__range': ['exact', 'lt', 'gt'],  # Include additional filters if needed
            'total_price__range': ['exact', 'lt', 'gt'],  # Include additional filters if needed
           
        }

Upvotes: 1

Soviut
Soviut

Reputation: 91545

First, you've got total_price as your field name but you're URL says total_cost.

Second, remove the __range suffix from your filter names. Anything with __ is part of the Django filtering. For example, if you were querying a model in Django for a value greater than something you'd do:

MyModel.objects.filter(price__gte=50)

Note the __gte suffix; That's how Django does filter modifiers. So your class should be something like:

class OrderFilter(filters.FilterSet):
    total_price = filters.RangeFilter(name='total_price')
    # ...

Then you can apply range filtering on that field in the query.

Upvotes: 7

Related Questions