Python 如何在没有其他查询的情况下筛选与反向相关的字段?

Python 如何在没有其他查询的情况下筛选与反向相关的字段?,python,django,django-models,django-rest-framework,django-filter,Python,Django,Django Models,Django Rest Framework,Django Filter,如何过滤由模型视图集生成的反向关系查询集,而不引起额外的查询 MRE: models.py: class Product(models.Model): name = models.CharField(max_length=45) image_url = models.URLField() class Item(models.Model): product = models.ForeignKey(Product, related_name='items', on_del

如何过滤由模型视图集生成的反向关系查询集,而不引起额外的查询

MRE: models.py:

class Product(models.Model):
    name = models.CharField(max_length=45)
    image_url = models.URLField()

class Item(models.Model):
    product = models.ForeignKey(Product, related_name='items',  on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.IntegerField()
views.py:

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.prefetch_related('items').all()
    serializer_class = ProductSerializer
    filter_backends = [filters.DjangoFilterBackend]
    filter_class = ProductFilter
serializers.py:

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = '__all__'

class ProductSerializer(serializers.ModelSerializer):
    items = ItemSerializer(many=True, read_only=True)

    class Meta:
        model = Product
        fields = '__all__'
filters.py:

import django_filters as filters

class ProductFilter(filters.FilterSet):
    price = filters.RangeFilter(field_name='items__price')
    quantity = filters.RangeFilter(field_name='items__quantity')

    class Meta:
        model = Product
        fields = {
            'name': ['icontains'],
        }
产品
模型的字段进行过滤效果良好,但
项目
反向关系完全忽略过滤

我从中找到了一个“解决方案”;即,通过
序列化方法字段进行过滤:

item_fieldset = {'price', 'quantity'}

class ProductSerializer(serializers.ModelSerializer):
    items = serializers.SerializerMethodField('get_items')

    class Meta:
        model = Product
        fields = '__all__'

    def get_items(self, product):
        params = self.context['request'].query_params
        filter_fields = item_fieldset.intersection(set(params))
        filters = {field: params.get(field) for field in filter_fields}
        serializer = ItemSerializer(instance=product.items.filter(**filters), many=True)
        return serializer.data
但这削弱了我的应用程序的性能


有更好的方法吗?

您是否测试过在
外键中设置
相关名称
选项,并将“items”作为值?@Rfroes87是的,相关名称在我的实际型号中设置。我更新了示例以包含它。您需要在
ProductFilter.Meta
类的fields属性中添加
price
quantity
。@alamshafi2263
Meta.fields
只是包含模型字段的快捷方式,不用于“声明”过滤器应该使用的字段。这样做会导致
TypeError:“Meta.fields”不能包含非模型字段名称:price
能否请您澄清您希望从过滤器中获得的名称-如果
price\u min=10
提供了您想要的产品
item\u price\u gte=10
(这将包括产品的所有项目,而不考虑它们的
price\u min
),或者您希望过滤器返回带有产品的queryset,并且仅返回
item\u price\u gte=10的项目?