Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically remove fields from serializer output

I'm developing an API with Django Rest framework, and I would like to dynamically remove the fields from a serializer. The problem is that I need to remove them depending on the value of another field. How could I do that? I have a serializer like:

class DynamicSerliazer(serializers.ModelSerializer):     type = serializers.SerializerMethodField()     url = serializers.SerializerMethodField()     title = serializers.SerializerMethodField()     elements = serializers.SerializerMethodField()      def __init__(self, *args, **kwargs):         super(DynamicSerliazer, self).__init__(*args, **kwargs)         if self.fields and is_mobile_platform(self.context.get('request', None)) and "url" in self.fields:             self.fields.pop("url") 

As you can see, I'm already removing the field "url" depending whether the request has been done from a mobile platform. But, I would like to remove the "elements" field depending on the "type" value. How should I do that?

Thanks in advance

like image 654
FVod Avatar asked Jun 23 '16 08:06

FVod


People also ask

What does serializer Is_valid do?

is_valid perform validation of input data and confirm that this data contain all required fields and all fields have correct types. If validation process succeded is_valid set validated_data dictionary which is used for creation or updating data in DB.

What is hyperlinked serializer?

HyperlinkedModelSerializer is a layer of abstraction over the default serializer that allows to quickly create a serializer for a model in Django. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds.


2 Answers

You can customize the serialization behavior by overriding the to_representation() method in your serializer.

class DynamicSerliazer(serializers.ModelSerializer):      def to_representation(self, obj):         # get the original representation         ret = super(DynamicSerializer, self).to_representation(obj)          # remove 'url' field if mobile request         if is_mobile_platform(self.context.get('request', None)):             ret.pop('url')          # here write the logic to check whether `elements` field is to be removed          # pop 'elements' from 'ret' if condition is True          # return the modified representation         return ret  
like image 200
Rahul Gupta Avatar answered Sep 29 '22 02:09

Rahul Gupta


You can create multiple serializers and choose the proper one in view

class IndexView(APIView):     def get_serializer_class(self):         if self.request.GET['flag']:             return SerializerA         return SerializerB 

use inheritance to make serializers DRY.

like image 40
glmvrml Avatar answered Sep 29 '22 01:09

glmvrml