Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#31981 closed Uncategorized (invalid)

many_to_many add() does not trigger post_save signal for the through class

Reported by: Kurt Wheeler Owned by: nobody
Component: Database layer (models, ORM) Version: 3.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a many-to-many relationship on my organization model: https://github.com/AlexsLemonade/resources-portal/blob/dev/api/resources_portal/models/organization.py#L50. As you can see, I specify through="OrganizationUserAssociation", and that class is defined here: https://github.com/AlexsLemonade/resources-portal/blob/dev/api/resources_portal/models/associations/organization_user_association.py

In a branch I am working on, I am adding a post-save signal to OrganizationUserAssociation. What I have found is that this isn't called when organization.members.add(user) is called.

I can't actually tell if this is a bug or just poorly documented. The only documentation I can find for the add() method is here: https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/ and it only shows the method being used for a single object. I think the post_save signal isn't being triggered because add() is doing a bulk update instead of creating the through class and saving that? Does add() handle multiple objects, is that why bulk update is being used? I can't actually find any documentation that indicates either way.

However, it makes sense to me that if add() is called with a single object, and there is a through class for the many-to-many field, then the through class should be used to create the relationship.

It seems like now I have to go through my code and find everywhere I called add() and do it the less convenient way. (The unfortunate thing is, that add() isn't that much more convenient than creating the association, so I wish I had just been warned so I could avoid it altogether.)

Change History (3)

comment:1 by Mariusz Felisiak, 4 years ago

Component: UncategorizedDatabase layer (models, ORM)
Resolution: invalid
Status: newclosed

In a branch I am working on, I am adding a post-save signal to OrganizationUserAssociation. What I have found is that this isn't called when organization.members.add(user) is called.

Yes because .add() doesn't call save() on OrganizationUserAssociation instances, this is a bulk operation. You should use the m2m_changed signal.

Closing per TicketClosingReasons/UseSupportChannels.

comment:2 by Kurt Wheeler, 4 years ago

add() being a bulk operation isn't documented anywhere and all the examples I found in the docs showed it being used with a singular object.

comment:3 by Mariusz Felisiak, 4 years ago

add() being a bulk operation isn't documented anywhere ..

That's not true, see Insert in bulk.

...and all the examples I found in the docs showed it being used with a singular object.

Docs that you've mentioned in the ticket description contains three example with multiple objects:

>>> a2.publications.add(p1, p2)
...
>>> p2.article_set.add(a4, a5)
...
>>> a2.publications.add(p1, p2, p3)
Note: See TracTickets for help on using tickets.
Back to Top