Подтвердить что ты не робот

Как вы фильтруете вложенный сериализатор в Django Rest Framework?

В Django Rest Framework, как вы фильтруете сериализатор, когда он вложен в другой сериализатор?

Мои фильтры накладываются на виды просмотра DRF, но когда вы вызываете сериализатор из другого сериализатора, просмотр вложенного сериализатора никогда не вызывается, поэтому вложенные результаты отображаются нефильтрованными.

Я попытался добавить фильтр на исходный viewet, но он, кажется, не фильтрует вложенные результаты, потому что вложенные результаты вызывают как отдельный предварительно отлаженный запрос. (Вложенный сериализатор - обратный поиск, вы видите.)

Можно ли добавить переопределение get_queryset() в самом вложенном сериализаторе (перемещение его из вида), чтобы добавить туда фильтр? Я тоже пробовал, что не повезло.

Это то, что я пробовал, но он даже не кажется вызванным:

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

Любая помощь оценена

Джон

4b9b3361

Ответ 1

Вы можете подклассифицировать ListSerializer и перезаписать метод to_representation.

По умолчанию метод to_representation вызывает data.all() на вложенном наборе запросов. Поэтому вам действительно нужно сделать data = data.filter(**your_filters) до вызова метода. Затем вам нужно добавить свой подклассифицированный ListSerializer как list_serializer_class в мета-вложенном сериализаторе.

  • Подкласс ListSerializer, перезаписывающий to_representation, а затем вызов super
  • добавить подклассифицированный ListSerializer в качестве мета list_serializer_class для вложенного Serializer

Вот соответствующий код для вашего образца.

class FilteredListSerializer(serializers.ListSerializer):

    def to_representation(self, data):
        data = data.filter(user=self.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