过滤动作装饰器 - Django Rest Framework

Jer*_*uez 5 python django django-filter django-rest-framework

我正在尝试使用 Django Rest Framework 上的装饰器操作过滤数据,如果我使用全局查询集(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')
Run Code Online (Sandbox Code Playgroud)

覆盖(动作)

@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)
Run Code Online (Sandbox Code Playgroud)

使用我的 url 'api/filter_shipping/(all filters here)'后,这仍然返回没有我请求的过滤器的所有数据。

谢谢你的帮助

小智 8

我认为如果您将查询参数与 URL 中的操作一起传递,则过滤器集成可以正常工作。以下是我采取的行动

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

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

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

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


小智 7

像这样添加 filter_queryset 函数。它对我有用。在 Django-filters 问题中找到了解决方案: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)
Run Code Online (Sandbox Code Playgroud)


sch*_*ngt 6

您可以过滤结果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)
Run Code Online (Sandbox Code Playgroud)

编辑:您可以根据需要创建自定义过滤器进行过滤。这是 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})
Run Code Online (Sandbox Code Playgroud)