Reputation: 1491
When I make a GET request to my /api/posts/ I recieve only author ID, but I also want author username to display it. How would I do that?
I want response to be something like this:
[
{
// all other stuff
author: {
id: 1,
username: "foo"
}
}
]
This is my Post viewset:
class PostViewSet(viewsets.ModelViewSet):
"""Handle CRUD for Posts"""
serializer_class = serializers.PostSerializer
authentication_classes = (TokenAuthentication,)
queryset = Post.objects.all()
def perform_create(self, serializer):
"""Set author to current user"""
serializer.save(user=self.request.user)
And this is what I get in response:
[
{
"id": 1,
"title": "Welcome!",
"description": "Welcome test!",
"created_at": "2019-09-21T01:05:58.170330Z",
"author": 1,
"community": 2
}
]
I want to do the same for community as well but I think I'll figure it out from the author solution.
Upvotes: 0
Views: 974
Reputation: 11
Since you have been able to retrieve the user object (author) via the perform_create function and you don't want to do any serious data manipulation, one way to do it is by adding this line of code to your serializer class. user_username = serializers.CharField(source="author.username", read_only=True). then add the user_username to the list/tuple stored in the fields. fields = ('', '', 'user_username')
example: in serializer.py
class PostSerializer(serializers.ModelSerializers):
user_username = serializers.CharField(source="author.username", read_only=True)
class Meta:
model = Post
fields = ('', '', 'user_username')
Note this method assumes that the user object (that is the author) has a "username" property/attribute
Upvotes: 0
Reputation: 88689
Use Nested Serializer,
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'username')
model = AuthorModel
class PostSerializer(...):
author = AuthorSerializer()
# other things
In such cases we have to override the to_representation
method. I've already answered it here, DRF: Simple foreign key assignment with nested serializers?
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'username')
model = AuthorModel
class PostSerializer(...):
# author = AuthorSerializer() # no need of this here
# other things
def to_representation(self, instance):
representation = super().to_representation(instance)
representation["author"] = AuthorSerializer(instance.author).data
return representation
Upvotes: 2
Reputation: 47374
You can override serializer's to_representation()
method:
class PostSerializer:
""" Your code here"""
def to_representation(self, instance):
ret = super().to_representation(instance)
ret['author'] = {"id": instance.author.id, "username": instance.author.username}
return ret
Upvotes: 1