leedjango
leedjango

Reputation: 411

How to create two models at once in django

I am making an API using DRF. Here I have a model called Blog and a model that refers to a Blog called Comment. When I create the Blog, I want to create the comments in the comments field together. Here is the json request and the code.

request

{
 comments: [
    {
     ...
    },
    {
     ...
    }
 ]
}

serializers.py

class CommentSerializer(serializers.ModelSerializer):

    class Meta:
        model = Comment
        fields = '__all__'

class BlogSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=100)
    body = serializers.CharField(max_length=255)
    comments = CommentSerializer(many=True)

    def create(self, validated_data):
        validated_comments = 
        validated_data.pop('comments')
        blog = Blog.objects.create(**validated_data)

        Comment.objects.bulk_create([
            Comment(**validated_comments, blog=blog) 
            for validated_comment in 
                validated_comments
        ])

        return blog

models.py

class Blog(models.Model):
    ...

class Comment(models.Model):
    ...
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    ...

How can I solve this code using queryset alone?

error

Got AttributeError when attempting to get a value for field `comments` on serializer `BlogSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Blog` instance.
Original exception text was: 'Blog' object has no attribute 'comments'.

Upvotes: 0

Views: 712

Answers (2)

Brian Destura
Brian Destura

Reputation: 12068

You can use bulk_create inside create() to create all the comments in one db hit.

class BlogSerializer(serializers.Serializer):
    ...
    def create(self, validated_data):
        validated_comments = validated_data.pop('comments')
        blog = Blog.objects.create(**validated_data)

        Comment.objects.bulk_create([
            Comment(**c, blog=blog) for c in validated_comments
        ])
        return blog

Upvotes: 1

Cheknov
Cheknov

Reputation: 2082

You have to create a Comment field in your Blog model.

Something like this:

class Blog(models.Model):
    ...
    comment = models.ForeignKey(
        Comment,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
    )

Upvotes: 0

Related Questions