The normal model save/delete signals were disabled because of the
potential for signal flood. If you add 100 objects to an m2m relation,
you would have received 100 signals. This is a time consuming activity
-- sending a signal consumes resources, even if it has no receivers;
and as soon as you *do* connect a receiver, you consume even more
resources. In the interests of performance, individual object signals
on m2m operations are disabled in favor of the grouped m2m_changed
signal.
> * For m2m fields with auto_created intermediate model, calling
> ``Model.m2m_field.add/remove/clear`` sends m2m_changed. However adding/
> removing relations using directly the through model (e.g.
> ``Model.m2m_field.through.objects.create(...)) does not send
> m2m_changed. Adding handlers for pre/post_save, pre/post_delete on the
> through model has no effect; the code specifically checks for
> auto_created models and does *not* send these signals in this case.
This sounds like an oversight to me.
> * For m2m fields with a given intermediate model,
> ``Model.m2m_field.add/remove`` are not exposed (at least for now but
> this is under discussion) and therefore m2m_changed is not sent;
> instead you have to handle addition/removal in pre/post_save, pre/
> post_delete handlers on the through model. However
> ``Model.m2m_field.clear()`` is exposed and does send m2m_changed; if
> there are pre/post_delete handlers on the through model, they are
> called as well after the m2m_changed.
> If nothing else, this creates an additional discrepancy between
> implicit and explicit through models. Switching from one to the other
> requires porting all the related signal handlers (a non-trivial task
> since m2m_changed has quite different API) and hope for the best. It
> also makes things harder for library code that attempts to work on
> arbitrary m2m fields, which normally wouldn't (or shouldn't) care
> whether the through model is auto_created or not.
Agreed, this certainly appears to be a inconsistency that needs to be
cleaned up. Moving to a manually defined through model shouldn't
require massive rewrites of signal handlers.
> Have these issues
> been raised before ? If so, what's the suggested way to use signals
> with m2m relations ?
No - these issues haven't been raised before (at least, not to my
knowledge). If you could open tickets for these issues, I'd be much
obliged. I'd be even more obliged if you'd try your hand at patches
:-)
Yours,
Russ Magee %-)