Django custom framework filter for POST request

In filters.py, I have CustomFilter

one that has values ​​of type ComboSortFilter

and IntegerListFilter

.

In views.py, I have defined a ViewSet with filter_class = CustomFilter

, and this works great for queries GET

using query string parameters in the url that are processed using custom filtering.

I also need to support queries POST

because some of the filter criteria are too large to accommodate the url.

So I added a method POST

to my ViewSet where I pull parameters from request.DATA

, then filters, serializes and paginates ...

in the mail method ViewSet in views.py:

queryset = MyModel.objects.filter(**filter_args)
page = self.paginate_queryset(queryset)
serializer = self.get_pagination_serializer(page)
return Response(serializer.data)

      

For simple filtering, this works great. However, the filtering I defined in mine CustomFilter

, which filters fields using ComboSortFilter

and IntegerListFilter

, is a little more complicated:

in filters.py:

class IntegerListFilter(django_filters.Filter):
    def filter(self, qs, value):
        if value not in (None, ''):
            integers = [int(v) for v in value.split(',')]
            return qs.filter(**{'{0}__{1}'.format(self.name, self.lookup_type): integers})
        return qs

class ComboSortFilter(django_filters.Filter):
    def __init__(self, threshold, lookup_type, order='ASC'):
        super(ComboSortFilter, self).__init__(lookup_type=lookup_type)
        self.threshold = threshold
        self.order = order

    def filter(self, qs, value):
        if value not in (None, ''):
            fields = [str(v) for v in value.split(',')]
            for field in fields:  # filters each field values relative to threshold
                qs = qs.filter(**{'{0}__{1}'.format(field, self.lookup_type): self.threshold})
            if self.order == 'DESC':
                fields = ['-{0}'.format(f) for f in fields]
            qs = qs.order_by(*fields)
        return qs

class CustomFilter(django_filters.FilterSet):
    thing_ids = IntegerListFilter(name="thing_id", lookup_type='in')
    sort_desc = ComboSortFilter(lookup_type='gte', threshold=100, order='DESC')
    sort_asc = ComboSortFilter(lookup_type='lte', threshold=100)

      

Is there a way to reference the CustomFilter

FilterSet, or one of the two custom filters from the PostSet post method? I wouldn't want to duplicate all this filtering code in views.py

to make it work.

All Django-rest-framework: filters documentation only includes simple examples that roll your own in views or use a filter class.Is there a way to call the filter class directly from the view, overriding the values ​​it normally gets from requests?

+3


source to share


1 answer


figured it out:



class MyPostViewSet(BaseModelViewSet):

    def post(self, request, *args, **kwargs):
        queryset = self.queryset
        filter_params = request.DATA or request.GET
        if filter_params:
            queryfilter = self.filter_class(filter_params, queryset=queryset)
            queryset = queryfilter.qs
        page = self.paginate_queryset(queryset)
        serializer = self.get_pagination_serializer(page)
        return Response(serializer.data)

      

+2


source







All Articles