class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE,
related_name='books')
title = models.CharField(max_length=200)
}}}
This works and creates two books linked to their author correctly:
{{{#!python
toni = Author.objects.create(name="Toni Morrison")
toni.books.create(title="The Bluest Eye")
toni.books.create(title="Beloved")
}}}
But if you try to use `bulk_create` to achieve the same, you get an error:
{{{#!python
toni = Author.objects.create(name="Toni Morrison")
toni.books.bulk_create([
Book(title="The Bluest Eye"),
Book(title="Beloved"),
])
}}}
This fails with an `IntegrityError` because `bulk_create` doesn't
automatically fill in the value of `Book.author` (the way it does it for
`create()`).
The documentation for `RelatedManager` [1] doesn't mention `bulk_create()`
but it's not clear to me if that means the operation is unsupported or not
(other methods like `count()` or `filter()` are not listed either but are
clearly supported). Because of this I wasn't sure whether to mark this
ticket as a bug or as a new feature.
Looking at the code [2], I can't find an explanation of why `bulk_create`
or `bulk_update` are not implemented either.
I've come up with the following implementation which seems to work (I
haven't tested it extensively):
{{{#!python
def bulk_create(self, objs, **kwargs):
def set_field_to_instance(instance):
setattr(instance, self.field.name, self.instance)
return instance
objs = map(set_field_to_instance, objs)
db = router.db_for_write(self.model, instance=self.instance)
return super(RelatedManager, self.db_manager(db)).bulk_create(objs,
**kwargs)
}}}
[1]
https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager
[2]
https://github.com/django/django/blob/aff7a58aef0264e5b2740e5df07894ecc0d7a580/django/db/models/fields/related_descriptors.py#L559
--
Ticket URL: <https://code.djangoproject.com/ticket/31539>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* owner: nobody => Baptiste Mispelon
* status: new => assigned
Comment:
I'll try to come up with a PR. If you don't see any activity from me
within a week you can assume I've given up and anyone can feel free to
reassign the ticket to themselves :)
--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:1>
* stage: Unreviewed => Accepted
Comment:
I think #27408 should be closed in favour of this ticket as we should only
do this automatically for reverse many-to-one managers of saved objects
and not systematically for all reverse relationship a model has.
--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:2>
* owner: Baptiste Mispelon => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:3>
* owner: (none) => Rahul Biswas
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:4>