0

I want to be able to accept a list query param using the standard application/x-www-form-urlencoded format, as stated in https://stackoverflow.com/a/9176496/4650346. For example to filter products by a list of categories, I would like to use:

http://my.api.com/products?category[]=shirts&category[]=sweaters

I can create a FilterSet that acomplish this multiple choice filtering, the issue is that it won't follow the standard as I am unable to add the suffix [] that express it is a list. The following class demonstrates the functionality that I need.

class MyFilter(django_filters.FilterSet):
    category = django_filters.ModelMultipleChoiceFilter(
        queryset=Category.objects.all(), 
        name='categories'
    )
    class Meta:
        model = MyModel
        fields = ['category',]

That code, will allow users to create requests as:

http://my.api.com/products?category=shirt&category=sweaters

Question is: how can I add the suffix [] to the GET parameters that represent a list in the URI?

Cheers,

Community
  • 1
  • 1

1 Answers1

1

This is a kind-of dirty fix I made to temporarily solve the problem. I extended the DjangoFilterBackend to override the filter_queryset method so whenever a field came in the form of category[], I add the category field to the request.query_params.

from rest_framework.filters import DjangoFilterBackend

class DjangoFilterBackendListsFix(DjangoFilterBackend):

    def filter_queryset(self, request, queryset, view):
        filter_class = self.get_filter_class(view, queryset)

        query_params = request.query_params.copy()
        for qp in request.query_params:
            if qp[-2:] == '[]':
                query_params.setlist(qp.rstrip('[]'), query_params.getlist(qp))

        if filter_class:
            return filter_class(query_params, queryset=queryset).qs

        return queryset

So now in settings.py I've got DjangoFilterBackendListsFix as my default filter backend.

I'm still hoping to get an elegant-er solution, but in the meantime my client can happily consume the Restful API.