【问题标题】:Django Rest Framework: Issue using OrderingFilter and django-filter simultaneouslyDjango Rest Framework:同时使用 OrderingFilter 和 django-filter 的问题
【发布时间】:2017-12-17 18:41:34
【问题描述】:

我有一个视图集,它需要通过参数灵活排序和通过参数过滤自定义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() 中应用才能生效,否则如果我在list() 中使用self.filter_queryset,尽管由filter_class = AssetFilterSet 指定,则会被绕过。

【问题讨论】:

  • 为什么不继承viewset.ListViewSetviewset.ModelViewSet,因为你使用的是模型,那么你不需要提供list,因为它会被继承。

标签: python django django-rest-framework


【解决方案1】:

我会回答我自己的问题。原来这是一个非常简单的修复;尽管在 SETTINGS 中全局指定了 DjangoFilterBackend,但您必须将 DjangoFilterBackendOrderingFilter 都明确包含为 filter_backends

这是工作代码:

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 过滤器会添加到它,而不是替换它。生活和学习!

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 2020-08-10
    • 2020-11-15
    • 2017-02-21
    • 2021-02-18
    相关资源
    最近更新 更多