#34733: m2m_changed signal is unaware if .set() method is being called
-------------------------------------+-------------------------------------
Reporter: lekjos | Owner: nobody
Type: New | Status: new
feature |
Component: Database | Version: dev
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 |
-------------------------------------+-------------------------------------
When a `related_m2m_field.set()` method is called, the `m2m_changed`
signal is fired four times for action: `pre_remove`, `post_remove`,
`pre_add`, and `post_add` (or `pre_clear` / `post_clear`).
This poses a problem if the signal is supposed to run validation on the
final state of the model. For example, let's say I have a model called
`Customer` with a many-to-many relation to `SubscriptionPlan` and I have a
`m2m_changed` signal that is supposed to validate if their
SubscriptionPlan is valid.
If I call `subscription_plans.set([some_plans])`, the many-to-many manager
will first call `subscription_plans.remove()` then `.add()` inside an
atomic transaction. If my signal validates on the first `remove()`, it
could be in an invalid state, even though it won't be by the time the
`.add()` completes.
To get around this, I had to create a custom ManyToManyField with a custom
RelatedManager that set an instance variable on the model when the
`.set()` method was called. I'd like to propose adding a feature to the
RelatedManager or to the signals to make the `m2m_changed` signal aware of
if the `.set()` method was called when running. This could be a private
attribute on the instance or extra information passed to the signal
receiver.
If this feature already exists or there's a decent workaround, let me know
and i'll close the ticket! Otherwise, I have a patch in mind that I can
raise a PR for and attach.
--
Ticket URL: <https://code.djangoproject.com/ticket/34733>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/010701897aa4eb79-e64e93d0-2dde-418d-94ee-6d45e4c9b0e7-000000%40eu-central-1.amazonses.com.