Динамически исключать или включать поле в сериализатор рамки Django REST
У меня есть сериализатор в структуре Django REST, который определяется следующим образом:
class QuestionSerializer(serializers.Serializer):
id = serializers.CharField()
question_text = QuestionTextSerializer()
topic = TopicSerializer()
Теперь у меня есть два вида API, которые используют вышеупомянутый сериализатор:
class QuestionWithTopicView(generics.RetrieveAPIView):
# I wish to include all three fields - id, question_text
# and topic in this API.
serializer_class = QuestionSerializer
class QuestionWithoutTopicView(generics.RetrieveAPIView):
# I want to exclude topic in this API.
serializer_class = ExamHistorySerializer
Одним из решений является запись двух разных сериализаторов. Но должно быть более легкое решение условно исключить поле из заданного сериализатора.
Ответы
Ответ 1
Вы пробовали эту технику
class QuestionSerializer(serializers.Serializer):
def __init__(self, *args, **kwargs):
remove_fields = kwargs.pop('remove_fields', None)
super(QuestionSerializer, self).__init__(*args, **kwargs)
if remove_fields:
# for multiple fields in a list
for field_name in remove_fields:
self.fields.pop(field_name)
class QuestionWithoutTopicView(generics.RetrieveAPIView):
serializer_class = QuestionSerializer(remove_fields=['field_to_remove1' 'field_to_remove2'])
Если нет, попробуйте.
Ответ 2
Создание нового сериализатора - путь. Условно удаляя поля в сериализаторе, вы добавляете дополнительную сложность и затрудняете быстрый поиск кода. Вы должны стараться не смешивать обязанности одного класса.
Следующими основными объектно-ориентированными принципами проектирования являются способы перехода.
QuestionWithTopicView - это QuestionWithoutTopicView, но с дополнительным полем.
class QuestionSerializer(serializers.Serializer):
id = serializers.CharField()
question_text = QuestionTextSerializer()
topic = TopicSerializer()
class TopicQuestionSerializer(QuestionSerializer):
topic = TopicSerializer()