Django-REST adding nested models

This is more of a best-practice question regarding Django-REST. As an example, I have the following 2 models:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
content = RichTextField(blank=True, null=True)
class Comment(models.Model):
post = models.ForeignKey(
Post, on_delete=models.CASCADE, related_name=‘comments’)
name = models.CharField(max_length=80)
body = models.TextField()

These have the following serializers:
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = (‘id’, ‘name’, ‘body’)
class PostSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Post
fields = (‘id’, ‘title’, ‘content’, ‘comments’)

So, every blog-post has a number of comments. Now I want to be able to write new comments to a post. My solution, which works so far, was to add this function to the PostSerializer:
def update(self, instance, validated_data):
comments_data = validated_data.pop(‘comments’)
comments = (instance.comments).all()
comments = list(comments)
instance.title = validated_data.get(
‘title’, instance.title)
instance.content = validated_data.get(
‘content’, instance.content)
for comment_data in comments_data:
if comments:
comment = comments.pop(0) = comment_data.get(‘name’,
comment.body = comment_data.get(‘body’, comment.body)
name = comment_data.get(‘name’,
body = comment_data.get(‘body’, comment.body)
Comment.objects.create(post=instance, name=name, body=body)
return instance

Now, this feels kind of like a “dirty” way of doing it, because I am creating a comment using an update command. My question would be: what is the best practice here? Creating a separate comment-api? Or perhaps adapting the create function? I thought about this last option having a try-except structure something like this?:
def create(self, validated_data):
comment_data = validated_data.pop(‘comments’)
post = Post.objects.create(**validated_data)
for comment_data in comment_data:
Comment.objects.create(post=post, **comment_data)
return post

Any advice on how best to do this is welcome!

Can you edit your code to use the code formatting so the whitespace appears properly? It’s very difficult to read currently.


Look at the example from DRF documentation on nested serializers. It’s pretty much what you wrote except for the try/except part.

+1 to the code formatting @CodenameTim