Django Rest Framework - nested serializer is not working like expected or how the docs explains

I have a post model and i have a post image model. I would like to show the images related to a post in the API, but I cannot seem to get it right.I only see the post data and not the related images.

Here are my post and post image models:

class Post(models.Model):

    EV = "Everybody"
    FO = "Followers"
    FR = "Friends"
    AUDIENCE = [
        (EV, "Everybody"),
        (FO, "Followers"),
        (FR, "Friends"),
    ]
    category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default=1)
    body = models.TextField("content", blank=True, null=True, max_length=5000)
    slug = AutoSlugField(populate_from=["category", "created_at"])
    video = models.FileField(upload_to=user_directory_path, null=True, blank=True)
    can_view = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
    can_comment = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
    user = models.ForeignKey(
        User, on_delete=models.CASCADE, verbose_name="user", related_name="user"
    )
    published = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "post"
        verbose_name_plural = "posts"
        db_table = "posts"
        ordering = ["created_at"]

    def __str__(self):
        return self.body[0:30]

    def get_absolute_url(self):
        return self.slug


class PostImage(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="post")
    image = models.FileField(
        upload_to=post_directory_path, default="posts/default.png", null=True
    )

    class Meta:
        db_table = "post_images"
        ordering = ["post"]

    def image_tag(self):
        return mark_safe(
            '<img src="/storage/%s" width="50" height="50" />' % (self.image)
        )

    image_tag.short_description = "Image"

This is the post and post images serializers:

class PostImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PostImage
        fields = ["id", "image", "post"]
        extra_kwargs = {
            "post": {"required": True},
        }


class PostSerializer(serializers.ModelSerializer):
    images = PostImageSerializer(many=True, read_only=True, required=False)

    class Meta:
        model = Post
        fields = [
            "id",
            "can_view",
            "can_comment",
            "category",
            "body",
            "images",
            "video",
            "user",
            "published",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ['category', 'user']

    def create(self, validated_data):
        user = User.objects.get(id=self.context['request'].data.get('user'))
        category = Category.objects.get(id=self.context['request'].data.get('category'))
        new_post = Post.objects.create(**validated_data, category=category, user=user)
        images = dict((self.context['request'].FILES).lists()).get('images', None)
        if images:
            for image in images:
                PostImage.objects.create(
                    image=image, post=new_post
                )
        return new_post

The post gets created fine and the images related to the post as well but if I go to the API end point to look at the post's data, I see all the fields but not the nested field with the images. What am I doing wrong please? How should you nest related fields otherwise?

A minor mistake, it's just a wrong reference. Change the field related name in models.py:

class PostImage(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
    ...
Back to Top