mirror of
https://github.com/django/django.git
synced 2025-10-23 21:59:11 +00:00
Fixed #6707 -- Added RelatedManager.set() and made descriptors' __set__ use it.
Thanks Anssi Kääriäinen, Carl Meyer, Collin Anderson, and Tim Graham for the reviews.
This commit is contained in:
@@ -135,12 +135,31 @@ Related objects reference
|
||||
:class:`~django.db.models.ForeignKey`\s where ``null=True`` and it also
|
||||
accepts the ``bulk`` keyword argument.
|
||||
|
||||
.. method:: set(objs, clear=False)
|
||||
|
||||
.. versionadded:: 1.9
|
||||
|
||||
Replace the set of related objects::
|
||||
|
||||
>>> new_list = [obj1, obj2, obj3]
|
||||
>>> e.related_set.set(new_list)
|
||||
|
||||
This method accepts a ``clear`` argument to control how to perform the
|
||||
operation. If ``False`` (the default), the elements missing from the
|
||||
new set are removed using ``remove()`` and only the new ones are added.
|
||||
If ``clear=True``, the ``clear()`` method is called instead and the
|
||||
whole set is added at once.
|
||||
|
||||
Note that since ``set()`` is a compound operation, it is subject to
|
||||
race conditions. For instance, new objects may be added to the database
|
||||
in between the call to ``clear()`` and the call to ``add()``.
|
||||
|
||||
.. note::
|
||||
|
||||
Note that ``add()``, ``create()``, ``remove()``, and ``clear()`` all
|
||||
apply database changes immediately for all types of related fields. In
|
||||
other words, there is no need to call ``save()`` on either end of the
|
||||
relationship.
|
||||
Note that ``add()``, ``create()``, ``remove()``, ``clear()``, and
|
||||
``set()`` all apply database changes immediately for all types of
|
||||
related fields. In other words, there is no need to call ``save()``
|
||||
on either end of the relationship.
|
||||
|
||||
Also, if you are using :ref:`an intermediate model
|
||||
<intermediary-manytomany>` for a many-to-many relationship, some of the
|
||||
@@ -158,6 +177,12 @@ new iterable of objects to it::
|
||||
>>> e.related_set = new_list
|
||||
|
||||
If the foreign key relationship has ``null=True``, then the related manager
|
||||
will first call ``clear()`` to disassociate any existing objects in the related
|
||||
set before adding the contents of ``new_list``. Otherwise the objects in
|
||||
``new_list`` will be added to the existing related object set.
|
||||
will first disassociate any existing objects in the related set before adding
|
||||
the contents of ``new_list``. Otherwise the objects in ``new_list`` will be
|
||||
added to the existing related object set.
|
||||
|
||||
.. versionchanged:1.9
|
||||
|
||||
In earlier versions, direct assignment used to perform ``clear()`` followed
|
||||
by ``add()``. It now performs a ``set()`` with the keyword argument
|
||||
``clear=False``.
|
||||
|
||||
@@ -127,7 +127,10 @@ Management Commands
|
||||
Models
|
||||
^^^^^^
|
||||
|
||||
* ...
|
||||
* Added the :meth:`RelatedManager.set()
|
||||
<django.db.models.fields.related.RelatedManager.set()>` method to the related
|
||||
managers created by ``ForeignKey``, ``GenericForeignKey``, and
|
||||
``ManyToManyField``.
|
||||
|
||||
Signals
|
||||
^^^^^^^
|
||||
@@ -192,6 +195,25 @@ used by the egg loader to detect if setuptools was installed. The ``is_usable``
|
||||
attribute is now removed and the egg loader instead fails at runtime if
|
||||
setuptools is not installed.
|
||||
|
||||
Related set direct assignment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:ref:`Direct assignment <direct-assignment>`) used to perform a ``clear()``
|
||||
followed by a call to ``add()``. This caused needlessly large data changes
|
||||
and prevented using the :data:`~django.db.models.signals.m2m_changed` signal
|
||||
to track individual changes in many-to-many relations.
|
||||
|
||||
Direct assignment now relies on the the new
|
||||
:meth:`django.db.models.fields.related.RelatedManager.set()` method on
|
||||
related managers which by default only processes changes between the
|
||||
existing related set and the one that's newly assigned. The previous behavior
|
||||
can be restored by replacing direct assignment by a call to ``set()`` with
|
||||
the keyword argument ``clear=True``.
|
||||
|
||||
``ModelForm``, and therefore ``ModelAdmin``, internally rely on direct
|
||||
assignment for many-to-many relations and as a consequence now use the new
|
||||
behavior.
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -1190,6 +1190,9 @@ be found in the :doc:`related objects reference </ref/models/relations>`.
|
||||
``clear()``
|
||||
Removes all objects from the related object set.
|
||||
|
||||
``set(objs)``
|
||||
Replace the set of related objects.
|
||||
|
||||
To assign the members of a related set in one fell swoop, just assign to it
|
||||
from any iterable object. The iterable can contain object instances, or just
|
||||
a list of primary key values. For example::
|
||||
|
||||
Reference in New Issue
Block a user