Search code examples
djangodjango-rest-frameworkdjango-viewsdjango-serializer

how to override returned serializer object that is returned with the response django rest framework serializer


I have a django rest framework project. I want to override the returned json object structure when a get request is made to display a specific way not similar to the database structure.

My current return object is displayed like so:

    {
        "id": 9,
        "namespace": "steve",
        "path": "something/another",
        "value": "this is a value",
        "person": 1
    },
    {
        "id": 11,
        "namespace": "namespace1",
        "path": "path2",
        "value": "anyoher value",
        "person": 2
    },
    {
        "id": 12,
        "namespace": "namespace1",
        "path": "path3",
        "value": "this dsiaalks",
        "person": 2
    },
    {
        "id": 13,
        "namespace": "namespace2",
        "path": "path4",
        "value": "asdfasdfasdf",
        "person": 2
    },

I want to switch the

"person":2 

to display

"user":{
    "userId":testUser
}
  • testUser is the username of the user with id 2 *

THis is my current serailzer:

from rest_framework import serializers
from .models import Preference
from django.contrib.auth.models import User


class PreferenceSerializer(serializers.ModelSerializer):
    person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)

    class Meta:
        model = Preference
        fields = ('id', 'namespace', 'path', 'value', 'person')

and this is the current model:

from django.db import models
from django.contrib.auth.models import User
from owf_framework.people.models import Person

class Preference(models.Model):
    id = models.BigAutoField(primary_key=True, null=False)
    version = models.BigIntegerField(default=1, null=False)
    path = models.CharField(max_length=200, null=False)
    namespace = models.CharField(max_length=200, null=False)
    value = models.TextField(null=False)
    user_id = models.BigIntegerField(null=False, default=1)
    person = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.namespace

    class Meta:
        db_table = 'preference'

the field person is a foreign key for user.


Solution

  • Hope this helps:

    serializers.py

    from rest_framework import serializers
    from .models import Preference
    from django.contrib.auth.models import User
    
    
    class PreferenceSerializer(serializers.ModelSerializer):
        person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)
    
        class Meta:
            model = Preference
            fields = ('id', 'namespace', 'path', 'value', 'person')
    
        def to_representation(self, instance):
            ret = super(PreferenceSerializer, self).to_representation(instance)
            # check the request is list view or detail view
            is_list_view = isinstance(self.instance, list)
            if is_list_view:
                person_id = ret.pop('person', None)
                user_obj = User.objects.filter(id=person_id).first()
                user_name = user_obj.username if user_obj else ""
                extra_ret = {
                    "user": {
                        "userId": user_name
                    }
                }
                ret.update(extra_ret)
            return ret