如何使用django_filters在DRF中接受标准格式的列表查询参数

时间:2015-08-26 15:56:40

标签: python filter django-rest-framework query-parameters multiple-choice

我希望能够使用标准application/x-www-form-urlencoded格式接受列表查询参数,如https://stackoverflow.com/a/9176496/4650346中所述。例如,要按类别列表过滤产品,我想使用:

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

我可以创建一个FilterSet来完成这个多选过滤,问题是它不会遵循标准,因为我无法添加表示它是列表的后缀[]。以下类演示了我需要的功能。

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

该代码将允许用户创建请求:

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

问题是:如何将后缀[]添加到表示URI中列表的GET参数?

干杯,

1 个答案:

答案 0 :(得分:1)

这是我为临时解决问题所做的种脏修复。我扩展了DjangoFilterBackend以覆盖filter_queryset方法,因此只要字段以category[]的形式出现,我就会将category字段添加到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

所以现在在settings.py中我有DjangoFilterBackendListsFix作为我的默认过滤后端。

我仍然希望得到一个优雅的解决方案,但与此同时,我的客户可以愉快地使用Restful API。