如何在 Django Rest Framework 中过滤嵌套的序列化程序? [英] How do you filter a nested serializer in Django Rest Framework?
问题描述
在 Django Rest Framework 中,如何过滤嵌套在另一个序列化程序中的序列化程序?
In Django Rest Framework, how do you filter a serializer when it's nested in another serializer?
我的过滤器被强加在 DRF 视图集中,但是当你从另一个序列化器内部调用一个序列化器时,嵌套序列化器的视图集永远不会被调用,所以嵌套的结果看起来是未经过滤的.
My filters are imposed in the DRF viewsets, but when you call a serializer from inside another serializer, the viewset of the nested serializer never gets called, so the nested results appear unfiltered.
我尝试在原始视图集上添加过滤器,但它似乎没有过滤嵌套结果,因为嵌套结果被称为单独的预提取查询.(嵌套序列化程序是反向查找,你看.)
I have tried adding a filter on originating viewset, but it doesn't seem to filter the nested results because the nested results get called as a separate pre-fretched query. (The nested serializer is a reverse lookup, you see.)
是否可以在嵌套序列化程序本身中添加 get_queryset() 覆盖(将其移出视图集),以在那里添加过滤器?我也试过了,但没有运气.
Is it possible to add a get_queryset() override in the nested serializer itself (moving it out of the viewset), to add the filter there? I've tried that, too, with no luck.
这是我尝试过的,但它似乎甚至没有被调用:
This is what I tried, but it doesn't even seem to get called:
class QuestionnaireSerializer(serializers.ModelSerializer):
edition = EditionSerializer(read_only=True)
company = serializers.StringRelatedField(read_only=True)
class Meta:
model = Questionnaire
def get_queryset(self):
query = super(QuestionnaireSerializer, self).get_queryset(instance)
if not self.request.user.is_staff:
query = query.filter(user=self.request.user, edition__hide=False)
return query
推荐答案
您可以将 ListSerializer 并覆盖 to_representation
方法.
You can subclass the ListSerializer and overwrite the to_representation
method.
默认情况下,to_representation
方法在嵌套查询集上调用 data.all()
.因此,您实际上需要在调用该方法之前使 data = data.filter(**your_filters)
.然后你需要在嵌套序列化器的元数据上添加你的子类 ListSerializer 作为 list_serializer_class .
By default the to_representation
method calls data.all()
on the nested queryset. So you effectively need to make data = data.filter(**your_filters)
before the method is called. Then you need to add your subclassed ListSerializer as the list_serializer_class on the meta of the nested serializer.
- 子类ListSerializer,覆盖
to_representation
然后调用super - 在嵌套的序列化器上添加子类 ListSerializer 作为元
list_serializer_class
- subclass ListSerializer, overwriting
to_representation
and then calling super - add subclassed ListSerializer as the meta
list_serializer_class
on the nested Serializer
这是您的示例的相关代码.
Here is the relevant code for your sample.
class FilteredListSerializer(serializers.ListSerializer):
def to_representation(self, data):
data = data.filter(user=self.context['request'].user, edition__hide=False)
return super(FilteredListSerializer, self).to_representation(data)
class EditionSerializer(serializers.ModelSerializer):
class Meta:
list_serializer_class = FilteredListSerializer
model = Edition
class QuestionnaireSerializer(serializers.ModelSerializer):
edition = EditionSerializer(read_only=True)
company = serializers.StringRelatedField(read_only=True)
class Meta:
model = Questionnaire
这篇关于如何在 Django Rest Framework 中过滤嵌套的序列化程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!