Orkhan Rustamli
Orkhan Rustamli

Reputation: 63

Django Rest Framework - Write for Relational nested Serializers

I am quite new DRF so I am sorry beforehand for any mistake.

For example, I have Post model which has Author as foreign key to NewUser model. When I list posts, instead of getting primary key of author, I wanted to get nested object with author details and that is why I created my serializer like this.

class PostAuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewUser
        fields = ["id", "email", "user_name"]


class PostSerializer(serializers.ModelSerializer):
    author = PostAuthorSerializer()

    class Meta:
        model = Post
        read_only_fields = ("slug",)
        fields = (
            "id",
            "title",
            "author",
            "excerpt",
            "content",
            "status",
            "slug",
        )
        lookup_field = "slug"

However, now I don`t how to /POST a post back. I searched for 2 days but cannot find a proper guide for understand how to do. My main goal is to learn/understand rather than solve the issue so a little bit explanation also would be great! I was really motivated to learn DRF, but I think it lacks a detailed documentation and examples in internet or at least I could not find answer to my question.

Error whith Author:id Error with dictionary

So, I want to learn 2 ways of posting:

  1. Representation is staying this way but I still /POST a post with showing "author":id
  2. Representation is staying this way and I /POST "author: {"email": "[email protected]", "user_name":"orkan.test"}" and still can create my post after getting author object

Thanks in advance!

Upvotes: 1

Views: 732

Answers (1)

Gokhan Sari
Gokhan Sari

Reputation: 7944

When you set the author field like author = PostAuthorSerializer(), it is not a primary key related field anymore. In order to achieve what you are trying to do, you need to use separate definitions (e.g. different serializers) for reading and writing.

But I would suggest a workaround like this:

class PostAuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewUser
        fields = ["id", "email", "user_name"]


class PostSerializer(serializers.ModelSerializer):
    author_data = serializers.SerializerMethodField()

    class Meta:
        model = Post
        read_only_fields = ("slug",)
        fields = (
            "id",
            "title",
            "author",
            "author_data",
            "excerpt",
            "content",
            "status",
            "slug",
        )
        lookup_field = "slug"

    def get_author_data(self, obj):
        return PostAuthorSerializer(instance=obj.author).data

Then you will be able to write author with the ID, and serialized author data will be available as author_data in the response.

Upvotes: 1

Related Questions