web-dev-qa-db-fra.com

Exclure ou inclure dynamiquement un champ dans Django REST serializer du framework)

J'ai un sérialiseur dans Django REST framework défini comme suit:

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

Maintenant, j'ai deux vues API qui utilisent le sérialiseur ci-dessus:

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

Une solution consiste à écrire deux sérialiseurs différents. Mais il doit y avoir une solution plus simple pour exclure conditionnellement un champ d'un sérialiseur donné.

28
Sudip Kafle

Avez-vous essayé cette technique

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'])

Sinon, essayez-le une fois.

50
Bishnu Bhattarai

La création d'un nouveau sérialiseur est la voie à suivre. En supprimant conditionnellement des champs dans un sérialiseur, vous ajoutez une complexité supplémentaire et vous rendez le code plus difficile à diagnostiquer rapidement. Vous devriez essayer d'éviter de mélanger les responsabilités d'une seule classe.

Suivre les principes de base de la conception orientée objet est la voie à suivre.

QuestionWithTopicView ( est un QuestionWithoutTopicView mais avec un champ supplémentaire.

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

class TopicQuestionSerializer(QuestionSerializer):
       topic = TopicSerializer()
13
user1042361