Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 = QuestionTextSerializer()     topic = TopicSerializer() 

Now I have two API views that use the above serializer:

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 

One solution is to write two different serializers. But there must be a easier solution to conditionally exclude a field from a given serializer.

like image 939
Sudip Kafle Avatar asked Jan 14 '15 03:01

Sudip Kafle


People also ask

How do you make a field optional in a serializer?

You could use a SerializerMethodField to either return the field value or None if the field doesn't exist, or you could not use serializers at all and simply write a view that returns the response directly. Update for REST framework 3.0 serializer. fields can be modified on an instantiated serializer.

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What does serializer Is_valid do?

The . is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers. ValidationError exception if there are validation errors.

Do we need Serializers in Django REST framework?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.


2 Answers

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.

like image 113
Bishnu Bhattarai Avatar answered Sep 29 '22 22:09

Bishnu Bhattarai


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() 
like image 41
user1042361 Avatar answered Sep 29 '22 21:09

user1042361