在动作装饰器上进行过滤-Django Rest Framework

时间:2018-11-19 04:00:48

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

我正在尝试在Django Rest Framework上使用装饰器操作来过滤数据,如果我使用全局queryset(get_queryset()函数),它可以完美工作,但是我需要在单独的函数中使用它。

我正在使用django-filter执行它。这是代码。

我的观点:

class ShippingAPI(viewsets.ModelViewSet):
    serializer_class = ShippingSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('origin__department', 'destination__department', 'first_collection_date', 'last_collection_date', 'vehicle')

替代(操作)

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = Shipping.objects.filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)

使用我的网址“ api / filter_shipping /(此处为所有过滤器)”后,它仍然返回所有数据,而没有我请求的过滤器。

感谢您的帮助

4 个答案:

答案 0 :(得分:2)

您可以从视图中覆盖普通的get_queryset方法并检查self.action

class ShippingAPI(viewsets.ModelViewSet):
    queryset = Shipping.objects.all()
    serializer_class = ShippingSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('origin__department', 'destination__department', 'first_collection_date', 'last_collection_date', 'vehicle')

    def get_queryset(self):
        queryset = super().get_queryset()

        if self.action == 'filter_shippings':
            queryset = queryset.filter(status=2, orderStatus=0)
        elif self.action == 'other_action':
            queryset = queryset.filter(...)  # other action filter

        return queryset

答案 1 :(得分:1)

添加filter_queryset这样的函数。它为我工作。 在Django过滤器问题中找到了解决方案:https://github.com/carltongibson/django-filter/issues/967

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = self.filter_queryset(self.get_queryset()).filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)

答案 2 :(得分:1)

如果您在 URL 中传递查询参数和操作,我认为过滤器集成工作正常。下面是我的操作

@action(methods=['GET'], detail=False)
def export(self, request): 
    queryset = self.get_queryset()
    filtered_queryset = self.filter_queryset(queryset)

当尝试从 DRF 可浏览 API 调用导出操作时,发送的请求是 /api/viewname/export/,它应该像
/api/viewname/export/?query_param_1=value1&?query_param_2=value2

将查询参数与操作一起传递将调用过滤器集类,因此您将在filtered_queryset 变量中获得过滤的查询集

还评论了 Github 问题:https://github.com/carltongibson/django-filter/issues/967#issuecomment-828220562

答案 3 :(得分:0)

您可以过滤get_queryset的结果以限制结果。

@action(detail=False, methods=['GET'])
def filter_shippings(self, request, **kwargs):
    queryset = self.get_queryset().filter(status=2, orderStatus=0)
    serializer = SearchShippingSerializer(queryset, many=True) #Yes, I am using another serializer, but it is solved,I use diferent if it is necesary
    return Response(serializer.data)

编辑: 您可以创建一个自定义过滤器来根据需要进行过滤。这是django-filter的文档中的示例。

import django_filters

class ProductFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['name', 'price', 'manufacturer']

def product_list(request):
    filter = ProductFilter(request.GET, queryset=Product.objects.all())
    return render(request, 'my_app/template.html', {'filter': filter})