I have two models as Follows:
class Book(models.Model):
title = models.CharField(max_length=100)
year = models.IntegerField(max_lenght=4)
author = models.ManyToManyField(null=true, blank=true)
class Author(models.CustomUser):
# some fields
Now, what I am looking to do is add an Author
to multiple Book
objects without iterating over the list of book objects.
Django's update method does not support ManyToManyField
as per docs. It says:
You can only set non-relation fields and ForeignKey fields using this method. To update a non-relation field, provide the new value as a constant. To update ForeignKey fields, set the new value to be the new model instance you want to point to.
So currently I am doing the following which is highly inefficient as I'll be hitting the database for each book object.
author = Author.objects.get(pk=1)
books = Book.objects.filter(**kwargs) # say this returns 100 objects
# each loop here will hit the database making it really inefficient
# for long lists.
for book in books:
book.authors.add(author)
book.save()
I am pretty sure there is a way around this, but I am just not able to find it in the documentation.
The answer is here:
https://stackoverflow.com/a/10116452/202168
In short, (in Django >= 1.4) you can do a bulk_create
on the through model, even if you haven't defined a custom through model.
Django - 2.27 Python 3.8
Let filter out the set of books
books = Book.objects.filter(...)
Create a author
author = Author.objects.create(...)
Add related_name for author field in Book model as author_book.
...
author = models.ManyToManyField(null=true, blank=true, related_name="author_book")
...
now add the author into set of books using reverse relation technique.
author.author_book.add(*books)
use * to unpack the query set
Note: we do not need to explicitly call save()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With