Python 如何在没有其他查询的情况下筛选与反向相关的字段?
如何过滤由模型视图集生成的反向关系查询集,而不引起额外的查询 MRE: models.py: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
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
。@alamshafi2263Meta.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的项目?