【问题标题】:Django rest framework custom filter for POST request用于 POST 请求的 Django REST 框架自定义过滤器
【发布时间】:2015-01-23 19:54:31
【问题描述】:

在 filters.py 中,我定义了一个 CustomFilter,其值类型为 ComboSortFilterIntegerListFilter

在views.py 中,我定义了一个具有filter_class = CustomFilter 的ViewSet,这对GET 请求非常有效,在url 中使用查询字符串参数,使用自定义过滤进行处理。

我还需要支持POST 请求,因为某些过滤条件太长,无法放入 URL。

所以我在 ViewSet 中添加了一个 post 方法,我从 request.DATA 中提取参数,然后过滤、序列化和分页...

在viewSet的views.py中的post方法中:

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

对于简单的过滤,上述工作正常。但是,我在 CustomFilter 中定义的过滤使用 ComboSortFilterIntegerListFilter 过滤字段有点复杂:

在 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's 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)

有没有办法从 ViewSet 的 post 方法中引用 CustomFilter FilterSet 或我的两个自定义过滤器中的任何一个?我不想必须在views.py 中复制所有这些过滤代码才能使其正常工作。

Django-rest-framework:filters 上的所有文档仅包含简单示例,要么在视图中滚动您自己,要么使用过滤器类。有没有办法直接从视图中调用过滤器类,覆盖它通常从查询字符串中获取的值?

【问题讨论】:

    标签: python django post filter django-rest-framework


    【解决方案1】:

    想通了:

    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)
    

    【讨论】:

    • 使用 Django 1.11,DRF 3.9.0:分页不起作用,因为 DRF 检查request.query_params。可能可以手动设置查询参数,但这需要一个单独的解决方法,如下所述:stackoverflow.com/questions/18930234/…
    猜你喜欢
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2018-12-20
    • 2016-04-07
    • 2014-02-17
    • 2019-11-24
    • 1970-01-01
    • 2020-05-11
    相关资源
    最近更新 更多