Reputation: 824
I want to customize the django rest framework serializer return object to a specific requirement. right now it returns the fields in a single object that is not nested.
{
"id": 9,
"namespace": "steve",
"path": "something/another",
"value": "this is a value"
},
and this is what I want the outcome to look like:
{
"id": 6,
"namespace": "tempnamespaced",
"path": "randompath",
"value": "anothertest",
"user": {
"userId": "testUser1"
}
}
So i want to add a nested object named user and add the userID value within the user.
the data that is returned in the userId is actually person.username person is a model username so the data is going to look like this when it is assigned and returned:
"user": {
"userId": {{person.username}}
}
I will attach mmy code below:
serializer:
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')
here is the get viewset:
@permission_classes((IsAuthenticated))
def get_queryset(self):
namespace = self.kwargs.get('namespace', None)
path = self.kwargs.get('path', None)
if namespace is None and path is None:
queryset = Preference.objects.all().filter(user_id=1)
if namespace and path is None:
queryset = Preference.objects.all().filter(user_id=1, namespace=namespace)
if namespace and path:
queryset = Preference.objects.all().filter(user_id=1, namespace=namespace, path=path)
return queryset
here is the mode:
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'
Upvotes: 1
Views: 3619
Reputation: 542
Define to_representation()
in your serializer:
class PreferenceSerializer(serializers.ModelSerializer):
# person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)
class Meta:
model = Preference
fields = ('id', 'namespace', 'path', 'value')
def to_representation(self, instance):
ret = super().to_representation(instance)
ret['user'] = {'userId': instance.person.username}
return ret
Upvotes: 4
Reputation:
You can add a method to your model to return the username instead of the field name.
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
def get_username(self):
return self.person.username
class Meta:
db_table = 'preference'
The Serializer can now use this method.
class PreferenceSerializer(serializers.ModelSerializer):
person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)
class Meta:
model = Preference
fields = ('id', 'namespace', 'path', 'value', 'person', 'get_username')
Upvotes: 0