фильтровать данные сериализатора django

Много раз мы обращаемся к данным через каталог сериализатора в соответствии с отношениями, определенными в моделях в Django (1.11.10). Как установить фильтр типа fetch-only is_active=1.

class DaasJobsSerializer(serializers.ModelSerializer):
    class Meta:
        model = DaasJobs
        fields = '__all__'

class DaasScheduleSerializer(serializers.ModelSerializer):
    jobs = DaasJobsSerializer(read_only=True,many=True)

    class Meta:
        model = DaasSchedule
        fields = '__all__'

Здесь я просто хочу установить фильтр для извлечения только тех заданий, для которых поле базы данных is_active=1 в этой строке, например DaasJobsSerializer(read_only=True,many=True, filter={"is_active":1}), как это сделать что-то вроде этого??

В настоящее время он дает мне все данные без проверки is_active, и я не хочу создавать для этого serializerMethodField.. потому что все методы, написанные ранее.. я просто устанавливаю поле is_active позже в таблицах в БД.


person DirtyHands    schedule 26.09.2018    source источник
comment
Фильтрация — это то, что вы делаете на уровне ViewSet, и вы можете использовать объект Prefetch для исправления связанных объектов.   -  person Willem Van Onsem    schedule 26.09.2018
comment
@WillemVanOnsem спасибо за ваш ответ, но как я могу использовать объект Prefetch при доступе к данным через сериализатор (jobs = DaasJobsSerializer (read_only = True, many = True))?   -  person DirtyHands    schedule 26.09.2018


Ответы (1)


Если вы хотите сделать это с помощью сериализаторов, вы можете попробовать переопределить ListSerializer и передать его как пользовательский list_serializer_class.

class IsActiveListSerializer(serializers.ListSerializer):

    def to_representation(self, data):
        data = data.filter(is_active=1)
        return super().to_representation(data)

В вашем сериализаторе:

class DaasJobsSerializer(serializers.ModelSerializer):
    class Meta:
        model = DaasJobs
        fields = '__all__'
        list_serializer_class = IsActiveListSerializer  # import it here

Конечно, это конкретный вариант использования, вы можете сделать более обобщенную версию ListSerializer для:

class FilteredListSerializer(serializers.ListSerializer):

    filter_kwargs = {}

    def to_representation(self, data):
        if not self.filter_kwargs or not isinstance(self.filter_kwargs, dict):
            raise TypeError(_('Invalid Attribute Type: `filter_kwargs` must be a of type `dict`.'))
        data = data.filter(**self.filter_kwargs)
        return super().to_representation(data)

И затем вы можете создать подкласс для создания других конкретных ListSerializers, таких как:

 class IsActiveListSerializer(FilteredListSerializer):
     filter_kwargs = {'is_active': 1}

и многие другие...

person Thomas Jiang    schedule 26.09.2018
comment
отличное решение моей проблемы, спасибо!! Здесь я просто хочу спросить вас, как я могу исследовать такие новые решения для меня в Django, вы уже знаете решение? если нет, то как вы подошли к поиску этого замечательного решения выше. как я могу улучшить свои навыки django, чтобы найти решение любой проблемы. - person DirtyHands; 26.09.2018
comment
Я продолжаю узнавать что-то новое каждый день. Вы всегда найдете что-то новое в документах. И нет лучшего способа, чем продолжать практиковаться. Что касается этого, я узнал об этом, когда работал над реальным проектом и у меня была именно эта потребность. Google, stackoverflow и документы — отличные ресурсы. - person Thomas Jiang; 26.09.2018