[Fixed]-DRF – serialize different models into one

1👍

You can add them as nested serializers to your UserSerializer. Something like this.

class ProfileSerializer(serializers.ModelSerializer)
    class Meta:
        model = Profile
        fields = '__all__'

class ProfilePicSerializer(serializers.ModelSerializer)
    class Meta:
        model = ProfilePic
        fields = '__all__'

class UserQuestionsSerializer(serializers.ModelSerializer)
    class Meta:
        model = UserQuestions
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer)
    profile = ProfileSerializer(many=False)
    profilepic = ProfilePicSerializer(many=False)
    user_questions = UserQuestionsSerializer(mane=True)

    class Meta:
        model = User
        fields = '__all__'

0👍

I struggled with the same issue about a month ago and found no good answer on SO.
Sardorbek’s answer is totally correct in case you dont care if json response is flat or not. JSON created by that code is something like:

{ 
  "profile": {"name": ..., "gender": ..., "birthday": ...,},
  "profile_pic": {"profilePic": ...., },
  "user_questions": [{...}, {...}, ...]
  User model attributes go here...
}

but if you want it to be flat, like:

{
    "name": ...,
    "gender": ...,
    "birthday": ...,
    ....
    "profilePic": ...,
    "user_questions": [{...}, {...}, ...],
    User model attributes go here...
}

You need a little hack here. Override to_internal_value in UserSerializer class in this way:

def to_internal_value(self, data):
    profile_info = {kv: data[kv] for kv in data if kv in list(ProfileSerializer.Meta.fields)}
    profile_pic_info = {kv: data[kv] for kv in data if kv in list(ProfilePicSerializer.Meta.fields)}

    return super(DeviceInfoSerializer, self).to_internal_value({
        'profile': profile_info,
        'profile_pic': profile_pic_info,
    })

You may need to override to_representation too, with similar idea.

Leave a comment