一开始我想说我找到了我的问题的部分答案(How can I apply a filter to a nested resource in Django REST framework?),但它不能100%覆盖我的问题。
我已经嵌套了3个模型:
我需要通过ModelB获得所有ModelA过滤,但我还需要过滤ModelB。
实施例。 / MODELA?modelab__modelb__id = 100
需要返回值:
[{id:1,
modelab: [{
id:10
modelb{
id: 100
}]
}]
}]
但它返回
[{id:1,
modelab: [{
id:10
modelb{
id: 100
},
id:11
modelb{
id: 102
}]
}]
}]
所以它只对第一级嵌套进行过滤。我想应用过滤器将应用于所有嵌套模型。
我的代码:
// models.py
class ModelA(models.Model):
name = models.TextField()
class ModelB(models.Model):
name = models.TextField()
class ModelAB(models.Model):
modelA = models.ForeignKey(ModelA)
modelB = models.ForeignKey(ModelB)
type_id = models.IntegerField(default=0)
// views.py
class ModelAFilter(filters.FilterSet):
vacancy_id = Filter(name="vacancy__id")
class Meta:
model = Candidate
fields = ('name', 'modelAB__modelB__name')
class ModelAViewSet(viewsets.ModelViewSet):
queryset = ModelA.objects.all()
serializer_class = ModelASerializer
filter_backends = (filters.DjangoFilterBackend, )
filter_class = ModelFilter
// serializers.py
class ModelBSerializer(serializers.ModelSerializer):
modelB = ModelB(many=True)
class Meta:
model = ModelB
fields = ('id', 'name')
class ModelABSerializer(serializers.ModelSerializer):
modelB= ModelBSerializer(many=True)
class Meta:
model = ModelB
fields = ('id', 'name', 'modelB',)
class ModelASerializer(serializers.ModelSerializer):
modelAB = ModelAB(many=True)
class Meta:
model = ModelA
fields = ('id', 'name', 'modelAB')
答案 0 :(得分:1)
您必须覆盖视图集上的get_queryset
方法并过滤prefetch_related
查询:
def get_queryset(self):
# get the filter value
modelb_id = self.request.query_params.get('modelab__modelb__id', None)
queryset_modelab = ModelAB.objects.all()
# you can use django-filter class here too
if modelb_id:
queryset_modelab = queryset_modelab.filter(modelb_id=modelb_id)
queryset_modelab.select_related('modelb')
queryset = (ModelA.objects
.prefetch_related(
Prefetch('modelab_set', queryset=queryset_modelab))
.all())
# modela filter class will work on this queryset
return queryset