Django Rest Framework:同时使用OrderingFilter和django-filter的问题

问题描述 投票:0回答:1

我有一个视图集,需要通过参数灵活排序和按参数过滤自定义list()覆盖。我能够通过django-filter获得订购以及过滤各种参数,但我不能让它们同时起作用。

这是我的简化views.py代码,用于排序结果:

class AssetViewSet(viewsets.GenericViewSet, AssetPaginationMixin,):

    queryset = Asset.objects.all()
    pagination_class = AssetPagination
    serializer_class = serializers.AssetSerializer
    filter_backends = (OrderingFilter, )
    ordering_fields = ('id', 'session_id')
    filter_class = AssetFilterSet

    def list(self, request):
        assets = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(assets, many=True)
        return Response(serializer.data)

以下是适用于过滤的代码:

class AssetViewSet(viewsets.GenericViewSet, AssetPaginationMixin,):

    queryset = Asset.objects.all()
    pagination_class = AssetPagination
    serializer_class = serializers.AssetSerializer
    filter_backends = (OrderingFilter, )
    ordering_fields = ('id', 'session_id')
    filter_class = AssetFilterSet

    def list(self, request):
        assets = AssetFilterSet(request.query_params)
        serializer = self.get_serializer(assets, many=True)
        return Response(serializer.data)

最后,我的filters.py代码:

class AssetFilterSet(django_filters.FilterSet):
    project_id = django_filters.NumberFilter()
    submitted = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool) 
    class Meta:
        model = Asset
        fields = ['project',
                  'submitted']

唯一的区别是list()的第一行。出于某种原因,似乎AssetFilterSet需要直接应用于list()才能生效,否则如果我在self.filter_queryset中使用list(),尽管被filter_class = AssetFilterSet指定,则需要绕过它。

python django django-rest-framework
1个回答
0
投票

我会回答我自己的问题。事实证明这是一个非常简单的修复;尽管在SETTINGS中全局指定了DjangoFilterBackend,你必须明确包括OrderingFilterfilter_backends作为DjangoFilterBackend

这是工作代码:

class AssetViewSet(viewsets.GenericViewSet, AssetPaginationMixin,):

    queryset = Asset.objects.all()
    pagination_class = AssetPagination
    serializer_class = serializers.AssetSerializer
    filter_backends = (DjangoFilterBackend, OrderingFilter,)
    ordering_fields = ('id', 'session_id')
    filter_class = AssetFilterSet

    def list(self, request):
        assets = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(assets, many=True)
        return Response(serializer.data)

我的印象是在SETTINGS中指定DjangoFilterBackend意味着默认情况下会包含它,并且添加一个filter_backends过滤器会添加它,而不是替换它。活到老,学到老!

© www.soinside.com 2019 - 2024. All rights reserved.