Dynamically Exclude Or Include A Field In Django Rest Framework Serializer
I have a serializer in Django REST framework defined as follows: class QuestionSerializer(serializers.Serializer): id = serializers.CharField() question_text = QuestionText
Solution 1:
Have you tried this technique
classQuestionSerializer(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 listfor field_name in remove_fields:
self.fields.pop(field_name)
classQuestionWithoutTopicView(generics.RetrieveAPIView):
serializer_class = QuestionSerializer(remove_fields=['field_to_remove1''field_to_remove2'])
If not, once try it.
Solution 2:
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()
Solution 3:
Extending above answer to a more generic one
classQuestionSerializer(serializers.Serializer):
def__init__(self, *args, **kwargs):
fields = kwargs.pop('fields', None)
super(QuestionSerializer, self).__init__(*args, **kwargs)
if fields isnotNone:
allowed = set(fields.split(','))
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
classQuestionWithoutTopicView(generics.RetrieveAPIView):
defget_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)
defget_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
Solution 4:
You can set fields
and exclude
properties of Meta
Here is an Example:
classDynamicFieldsModelSerializer(serializers.ModelSerializer):
classMeta:
model = User
exclude = ['id', 'email', 'mobile']
def__init__(self, *args, **kwargs):
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
# @note: For example based on user, we will send different fieldsif self.context['request'].user == self.instance.user:
# Or set self.Meta.fields = ['first_name', 'last_name', 'email', 'mobile',]
self.Meta.exclude = ['id']
Post a Comment for "Dynamically Exclude Or Include A Field In Django Rest Framework Serializer"