#27782 closed Cleanup/optimization (needsinfo)
Model signals and Many2Many fields
Reported by: | Дилян Палаузов | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | 1.10 |
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
The documentation for Django 1.10 concerning signals is unclear when a models.ManyToManyField is updated, if the signal listeners of both models will be triggered, or only the listeners of one of the models.
class A(models.Model): i = models.IntegerField() class B(models.Model): j = models.ManyToMayField(A) @receiver(post_save, sender=B) def X(sender, instance, created, kwargs): print("X triggered") @receiver(post_save, sender=A) def Y(sender, instance, created, kwargs): print("Y triggered") a = A.objects.create(i=1) b = B.objects.create() b.j.add(i) b.save()
Will this call both X() and Y(), as both models are equally updated?
Change History (8)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
With this model:
from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class A(models.Model): i = models.IntegerField() class B(models.Model): j = models.ManyToManyField(A) @receiver(post_save, sender=A) def XA(*args, **kwargs): print("XA") @receiver(post_save, sender=B) def XB(*args, **kwargs): print("XB")
I do
import my.models a = my.models.A.objects.create(i=5) b = my.models.B.objects.create() b.j.add(a)
The first assignment prints XA
and the second prints XB
as expected.
The last line effectively modifies both objects - a and b - and persists the change. The latter means that a save() is called implicitly on both a and b, so I expect to see again XA
and XB
.
Or with other words, when a ManyToManyField is saved, what signals are sent from which model?
comment:3 by , 8 years ago
The latter means that a save() is called implicitly on both a and b
This is an incorrect assumption. Please read the docs for add()
.
comment:5 by , 8 years ago
I'm not sure what to say besides what the documentation already says, "Using add()
with a many-to-many relationship, however, will not call any save()
methods." Creating a many-to-many relationship does not require saving any related objects. Instead the m2m_changed
signal is sent.
Could you point to the unclear documentation and suggest a clarification?
comment:6 by , 8 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:7 by , 8 years ago
I propose to repeat at the place where signals are described, that using add() does not trigger a signal.
I'm not sure what would imply that A's
post_save
signal is sent considering there aren't any calls toa.save()
. Could you point to the unclear documentation and suggest a clarification?