crodev
crodev

Reputation: 1491

How to return Posts author ID and username instead of just ID in DjangoREST

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

Answers (3)

devocip
devocip

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

JPG
JPG

Reputation: 88689

Use Nested Serializer,


class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'username')
        model = AuthorModel


class PostSerializer(...):
    author = AuthorSerializer()
    # other things

UPDATE

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

neverwalkaloner
neverwalkaloner

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

Related Questions