Dynamically exclude or include a field in Django REST framework serializer Dynamically exclude or include a field in Django REST framework serializer python python

Dynamically exclude or include a field in Django REST framework serializer


Have you tried this 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'])

If not, once try it.


Creating a new serializer is the way to go. By conditionally removing fields in a serializer you are adding extra complexity and making you code harder to quickly diagnose. You should try to avoid mixing the responsibilities of a single class.

Following basic object oriented design principles is the way to go.

QuestionWithTopicView is a QuestionWithoutTopicView but with an additional field.

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


Extending above answer to a more generic one

class QuestionSerializer(serializers.Serializer):    def __init__(self, *args, **kwargs):        fields = kwargs.pop('fields', None)        super(QuestionSerializer, self).__init__(*args, **kwargs)        if fields is not None:            allowed = set(fields.split(','))            existing = set(self.fields)            for field_name in existing - allowed:                self.fields.pop(field_name)class QuestionWithoutTopicView(generics.RetrieveAPIView):    def get_serializer(self, *args, **kwargs):        kwargs['context'] = self.get_serializer_context()        fields = self.request.GET.get('display')        serializer_class = self.get_serializer_class()        return serializer_class(fields=fields,*args, **kwargs)    def get_serializer_class(self):        return QuestionSerializer    

Now we can give a query parameter called display to output any custom display format http://localhost:8000/questions?display=param1,param2