在Django REST框架序列化程序中动态排除或包含字段

Sud*_*fle 31 python django serialization django-serializer django-rest-framework

我在Django REST框架中有一个序列化程序,定义如下:

class QuestionSerializer(serializers.Serializer):
    id = serializers.CharField()
    question_text = QuestionTextSerializer()
    topic = TopicSerializer()
Run Code Online (Sandbox Code Playgroud)

现在我有两个使用上述序列化程序的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
Run Code Online (Sandbox Code Playgroud)

一种解决方案是编写两个不同的序列化器.但必须有一个更容易的解决方案来有条件地从给定的序列化器中排除一个字段.

Bis*_*rai 54

你尝试过这种技术吗?

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'])
Run Code Online (Sandbox Code Playgroud)

如果没有,一旦尝试.

  • 这应该工作.但是我期待在Django休息框架中构建一些东西.如果我找不到更清洁的解决方案,我会用它. (4认同)
  • 应该注意,这仅适用于只读序列化器.这将在执行CRUD操作的序列化程序上创建或更新时中断. (3认同)
  • @SudipKafle DRF 文档中建议的类似方法还有 http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields (2认同)
  • 小心这种方法,它不适用于 `many=True` (2认同)

use*_*361 15

创建新的序列化程序是可行的方法.通过有条件地删除序列化程序中的字段,您将增加额外的复杂性并使您更难以快速诊断代码.您应该尽量避免混合单个类的职责.

遵循基本的面向对象设计原则是要走的路.

QuestionWithTopicView 是一个 QuestionWithoutTopicView,但有一个额外的字段.

class QuestionSerializer(serializers.Serializer):
        id = serializers.CharField()
        question_text = QuestionTextSerializer()
        topic = TopicSerializer()

class TopicQuestionSerializer(QuestionSerializer):
       topic = TopicSerializer()
Run Code Online (Sandbox Code Playgroud)