diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2010-01-13 11:07:16 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2010-01-13 11:07:16 +0000 |
| commit | 6afd505b5be528bc5728bc9b9acd48276be457b4 (patch) | |
| tree | 3b30c5772405413fab9c4d8b1aa689cfab4b0fbf /docs | |
| parent | f56f6e94054dcafbdfc555460e3119b1ad018352 (diff) | |
Fixed #5390 -- Added signals for m2m operations. Thanks to the many people (including, most recently, rvdrijst and frans) that have contributed to this patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12223 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/ref/signals.txt | 117 | ||||
| -rw-r--r-- | docs/topics/signals.txt | 3 |
2 files changed, 120 insertions, 0 deletions
diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt index b54a895000..54efbff89e 100644 --- a/docs/ref/signals.txt +++ b/docs/ref/signals.txt @@ -170,6 +170,123 @@ Arguments sent with this signal: Note that the object will no longer be in the database, so be very careful what you do with this instance. +m2m_changed +----------- + +.. data:: django.db.models.signals.m2m_changed + :module: + +Sent when a :class:`ManyToManyField` is changed on a model instance. +Strictly speaking, this is not a model signal since it is sent by the +:class:`ManyToManyField`, but since it complements the +:data:`pre_save`/:data:`post_save` and :data:`pre_delete`/:data:`post_delete` +when it comes to tracking changes to models, it is included here. + +Arguments sent with this signal: + + ``sender`` + The intermediate model class describing the :class:`ManyToManyField`. + This class is automatically created when a many-to-many field is + defined; it you can access it using the ``through`` attribute on the + many-to-many field. + + ``instance`` + The instance whose many-to-many relation is updated. This can be an + instance of the ``sender``, or of the class the :class:`ManyToManyField` + is related to. + + ``action`` + A string indicating the type of update that is done on the relation. + This can be one of the following: + + ``"add"`` + Sent *after* one or more objects are added to the relation + ``"remove"`` + Sent *after* one or more objects are removed from the relation + ``"clear"`` + Sent *before* the relation is cleared + + ``reverse`` + Indicates which side of the relation is updated (i.e., if it is the + forward or reverse relation that is being modified). + + ``model`` + The class of the objects that are added to, removed from or cleared + from the relation. + + ``pk_set`` + With the ``"add"`` and ``"remove"`` action, this is a list of + primary key values that have been added to or removed from the relation. + + For the ``"clear"`` action, this is ``None``. + +For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled +like this: + +.. code-block:: python + + class Topping(models.Model): + # ... + + class Pizza(models.Model): + # ... + toppings = models.ManyToManyField(Topping) + +If we would do something like this: + +.. code-block:: python + + >>> p = Pizza.object.create(...) + >>> t = Topping.objects.create(...) + >>> p.toppings.add(t) + +the arguments sent to a :data:`m2m_changed` handler would be: + + ============== ============================================================ + Argument Value + ============== ============================================================ + ``sender`` ``Pizza.toppings.through`` (the intermediate m2m class) + + ``instance`` ``p`` (the ``Pizza`` instance being modified) + + ``action`` ``"add"`` + + ``reverse`` ``False`` (``Pizza`` contains the :class:`ManyToManyField`, + so this call modifies the forward relation) + + ``model`` ``Topping`` (the class of the objects added to the + ``Pizza``) + + ``pk_set`` ``[t.id]`` (since only ``Topping t`` was added to the relation) + ============== ============================================================ + +And if we would then do something like this: + +.. code-block:: python + + >>> t.pizza_set.remove(p) + +the arguments sent to a :data:`m2m_changed` handler would be: + + ============== ============================================================ + Argument Value + ============== ============================================================ + ``sender`` ``Pizza.toppings.through`` (the intermediate m2m class) + + ``instance`` ``t`` (the ``Topping`` instance being modified) + + ``action`` ``"remove"`` + + ``reverse`` ``True`` (``Pizza`` contains the :class:`ManyToManyField`, + so this call modifies the reverse relation) + + ``model`` ``Pizza`` (the class of the objects removed from the + ``Topping``) + + ``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the + relation) + ============== ============================================================ + class_prepared -------------- diff --git a/docs/topics/signals.txt b/docs/topics/signals.txt index 6f66b036c7..e3f5b90d89 100644 --- a/docs/topics/signals.txt +++ b/docs/topics/signals.txt @@ -29,6 +29,9 @@ notifications: Sent before or after a model's :meth:`~django.db.models.Model.delete` method is called. + * :data:`django.db.models.signals.m2m_changed` + + Sent when a :class:`ManyToManyField` on a model is changed. * :data:`django.core.signals.request_started` & :data:`django.core.signals.request_finished` |
