Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest serialize a field with diffrent read and write data type

I use django rest with neo4j. For my project when create a node i will get a list of ids for nodes that current node will relation to them. For representation I will represent a list of dicts that contain data of nodes connected to this node. But because of serializer that is list of strings, dicts will convert to string.

My problem is not about neo4j. I ask for a way in django rest to have different data type serializing for read and write for same field.

This is my code:

class ScreenSerializer(serializers.Serializer):
    questions = serializers.ListSerializer(child=serializers.CharField())

    def create(self, validated_data):
        questions = validated_data.pop('questions')
        screen = Screen(**validated_data).save()
        for question_uid in questions:
            # connect relation in neo4j between screen and questions
        screen.save()
        return screen

    def to_representation(self, obj):
        obj.questions = # List of dicts that contain every connected node data
        obj = super().to_representation(obj)
        return obj

I tried read_only, write_only but that didn't helped me.

Input example: ['123456', '654321']

Output example: [{some data of node 123456},{some data of node 654321}]

But my current output is like this: ['{some data of node 123456}', '{some data of node 654321}']

EDIT:

Answer that worked base of neverwalkaloner answer:

    def to_representation(self, obj):
        obj.questions = # List of dicts that contain every connected node data
        self.fields['questions'] = serializers.ListSerializer(child=serializers.DictField())
        obj = super().to_representation(obj)
        return obj
like image 419
mastisa Avatar asked May 28 '18 04:05

mastisa


1 Answers

You can use custom question's serializer like this:

class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Question
        fields = ['field1', 'field2']

class ScreenSerializer(serializers.Serializer):

    def create(self, validated_data):
        questions = validated_data.pop('questions')
        screen = Screen(**validated_data).save()
        for question_uid in questions:
            # connect relation in neo4j between screen and questions
        screen.save()
        return screen

    def to_representation(self, obj):
        self.fields['questions'] = QuestionSerializer(many=True)
        return super().to_representation(obj)

Note inside to_representation method you should override serializer's field questions. You can access it through self.fields['questions'] syntax.

like image 61
neverwalkaloner Avatar answered Nov 01 '22 10:11

neverwalkaloner