AdamY
AdamY

Reputation: 921

Saving objects and their related objects at the same time in Django

In Django, is there a way to create a object, create its related objects, then save them all at once?

For example, in the code below:

from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=255)
    body = models.CharField(max_length=255)


class Tag(models.Model):
    post = models.ForeignKey(Post)
    title = models.CharField(max_length=255)

post = Post(title='My Title', body='My Body')
post.tag_set = [Tag(post=post, title='test tag'), Tag(post=post, title='second test tag')]
post.save()

I create a Post object. I then also want to create and associate my Tag objects. I want to avoid saving the Post then saving the Tags because if a post.save() succeeds, then a tag.save() fails, I'm left with a Post with no Tags.

Is there a way in Django to save these all at once or at least enforce better data integrity?

Upvotes: 17

Views: 16896

Answers (2)

Ian Kirkpatrick
Ian Kirkpatrick

Reputation: 1960

override save...

class Post(models.Model):

    ...

    def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        for tag in self.tag_set:
            tag.save()

This way you don't have to write the transaction thing over and over again. If you want to use transactions, just implement it in the save method instead of doing the loop.

Upvotes: 4

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

transactions to the rescue !

from django.db import transaction

with transaction.atomic():
   post = Post.objects.create('My Title', 'My Body')
   post.tag_set = [Tag(post, 'test tag'), Tag(post, 'second test tag')]

As a side note: I think you really want a many to many relationship between Post and Tag...

Upvotes: 14

Related Questions