Django Rest Framework自定义过滤器-按孩子数进行顺序搜索

Dan*_*kov 1 django django-rest-framework

我将DRFdjango-rest-framework-filters一起使用

模型是:具有许多OrderItems的订单。任务是创建过滤器,该过滤器使您能够按订单项计数或按计数排序搜索订单。

在我的view.py中:

class OrderFilter(filters.FilterSet):
    order_items_count = filters.NumberFilter(name="order_items__count")
    customer = filters.RelatedFilter(
        CustomerFilter,
        name='customer',
        queryset=Customer.objects.all(),
        )

    class Meta:
        model = Order
        fields = {
            'internal_code': ['icontains'],
            'notes': ['icontains'],
            'status': ['exact'],
            'complete': ['exact'],
            'order_items_count': ['exact']
            }

class OrderViewSet(BaseViewSet, viewsets.ModelViewSet):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    filter_class = OrderFilter
    filter_backends = (
        OrderingFilter,
        DjangoFilterBackend,
        )
    ordering_fields = (
        'internal_code',
        'notes',
        'status',
        'complete',
        'customer__title',
        'order_items__count',
        )
Run Code Online (Sandbox Code Playgroud)

应要求/orders?order_items_count=2我得到了错误:相关字段具有无效的查找:计数

如何为模型的子代数创建自定义过滤器?谢谢。

PS这是我对stackowerflow的第一个问题,对不起样式错误。

zap*_*.10 6

首先,将视图集上的查询集更改为:

queryset = Order.objects.annotate(order_items_count=Count('order_items')).all()

这将确保queryset具有字段 order_items_count

使用它作为您的order_items_count过滤器

order_items_count = filters.NumberFilter(method='filter_orders_by_item_count')

def filter_orders_by_item_count(self, queryset, name, value):
    return queryset.filter(order_items_count=value)
Run Code Online (Sandbox Code Playgroud)

对于非模型字段的订购,请使用链接[1]中所述的自定义订购过滤器

自定义过滤器上的过滤器方法为:

def filter(self, qs, value):
        # OrderingFilter is CSV-based, so `value` is a list
        if any(v in ['order_items_count', '-order_items_count'] for v in value):
            return queryset.order_by(value)
        return super(CustomOrderingFilter, self).filter(qs, value)
Run Code Online (Sandbox Code Playgroud)

[1] https://django-filter.readthedocs.io/en/develop/ref/filters.html#adding-custom-filter-choices