如何在 Django Rest Framework 中过滤嵌套的序列化程序? [英] How do you filter a nested serializer in Django Rest Framework?

查看:35
本文介绍了如何在 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.

  1. 子类ListSerializer,覆盖to_representation然后调用super
  2. 在嵌套的序列化器上添加子类 ListSerializer 作为元 list_serializer_class
  1. subclass ListSerializer, overwriting to_representation and then calling super
  2. 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆