[Django] #31539: Add support for bulk operations on reverse many-to-one manager

14 views
Skip to first unread message

Django

unread,
May 5, 2020, 9:30:35 AM5/5/20
to django-...@googlegroups.com
#31539: Add support for bulk operations on reverse many-to-one manager
-------------------------------------+-------------------------------------
Reporter: Baptiste | Owner: nobody
Mispelon |
Type: New | Status: new
feature |
Component: Database | Version: master
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Using the `Book` and `Author` models from the docs:
{{{#!python
class Author(models.Model):
name = models.CharField(max_length=100)

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.

Django

unread,
May 5, 2020, 9:38:04 AM5/5/20
to django-...@googlegroups.com
#31539: Add support for bulk operations on reverse many-to-one manager
-------------------------------------+-------------------------------------
Reporter: Baptiste Mispelon | Owner: Baptiste
| Mispelon
Type: New feature | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Baptiste Mispelon):

* 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>

Django

unread,
May 5, 2020, 9:50:21 AM5/5/20
to django-...@googlegroups.com
#31539: Add support for bulk operations on reverse many-to-one manager
-------------------------------------+-------------------------------------
Reporter: Baptiste Mispelon | Owner: Baptiste
| Mispelon
Type: New feature | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* 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>

Django

unread,
Mar 21, 2023, 5:28:49 AM3/21/23
to django-...@googlegroups.com
#31539: Add support for bulk operations on reverse many-to-one manager
-------------------------------------+-------------------------------------
Reporter: Baptiste Mispelon | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: dev

(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* owner: Baptiste Mispelon => (none)
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:3>

Django

unread,
May 1, 2023, 9:51:32 AM5/1/23
to django-...@googlegroups.com
#31539: Add support for bulk operations on reverse many-to-one manager
-------------------------------------+-------------------------------------
Reporter: Baptiste Mispelon | Owner: Rahul
| Biswas

Type: New feature | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Rahul Biswas):

* owner: (none) => Rahul Biswas


* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/31539#comment:4>

Reply all
Reply to author
Forward
0 new messages