Reputation: 1088
Using Django 1.9 and Python 3.4 I want to copy an existing model instance and all its related data. Below is an example of how I have currently achieved this. My question is, is there a better way?
I have read over posts e.g. Duplicating model instances and their related objects in Django / Algorithm for recusrively duplicating an object this one but, they are over 8 years old and no longer work with Django 1.9+.
Below is how I try to achieve this already, ok or a better way in Django 1.9?
Models
class Book(models.Model):
name = models.CharField(max_length=80)
class Contributor(models.Model):
name = models.CharField(max_length=80)
books = models.ForeignKey("Book", related_name="contributors")
The copy function. I have to recreate contributors after saving the new Book instance otherwise, it will assign existing contributors from the instance I'm copying from.
def copy_book(self, id):
view = self.context['view']
book_id = id
book = Book.objects.get(pk=book_id)
copy_book_contributors = book.contributors.all()
book.id = None
# make a copy of the contributors items.
book.save()
for item in copy_book_contributors:
# We need to copy/save the item as it will reassign the existing one.
item.id = None
item.save()
book.contributors.add(item)
Upvotes: 6
Views: 10330
Reputation: 19831
For this particular case, you can bulk_create
the contributors
:
contributor_names = list(book.contributors.values_list('name', flat=True))
book.id = None
book.save()
# create the contributor object with the name and new book id.
contributors = [Contributor(name=name, book_id=book.id) for name in contributor_names]
Contributor.objects.bulk_create(contributors)
Upvotes: 6