mirror of
https://github.com/django/django.git
synced 2024-12-24 18:16:19 +00:00
4a954cfd11
This patch does not remove all occurrences of the words in question. Rather, I went through all of the occurrences of the words listed below, and judged if they a) suggested the reader had some kind of knowledge/experience, and b) if they added anything of value (including tone of voice, etc). I left most of the words alone. I looked at the following words: - simply/simple - easy/easier/easiest - obvious - just - merely - straightforward - ridiculous Thanks to Carlton Gibson for guidance on how to approach this issue, and to Tim Bell for providing the idea. But the enormous lion's share of thanks go to Adam Johnson for his patient and helpful review.
220 lines
8.7 KiB
Plaintext
220 lines
8.7 KiB
Plaintext
=========================
|
|
Related objects reference
|
|
=========================
|
|
|
|
.. currentmodule:: django.db.models.fields.related
|
|
|
|
.. class:: RelatedManager
|
|
|
|
A "related manager" is a manager used in a one-to-many or many-to-many
|
|
related context. This happens in two cases:
|
|
|
|
* The "other side" of a :class:`~django.db.models.ForeignKey` relation.
|
|
That is::
|
|
|
|
from django.db import models
|
|
|
|
class Reporter(models.Model):
|
|
# ...
|
|
pass
|
|
|
|
class Article(models.Model):
|
|
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
|
|
|
|
In the above example, the methods below will be available on
|
|
the manager ``reporter.article_set``.
|
|
|
|
* Both sides of a :class:`~django.db.models.ManyToManyField` relation::
|
|
|
|
class Topping(models.Model):
|
|
# ...
|
|
pass
|
|
|
|
class Pizza(models.Model):
|
|
toppings = models.ManyToManyField(Topping)
|
|
|
|
In this example, the methods below will be available both on
|
|
``topping.pizza_set`` and on ``pizza.toppings``.
|
|
|
|
.. method:: add(*objs, bulk=True, through_defaults=None)
|
|
|
|
Adds the specified model objects to the related object set.
|
|
|
|
Example::
|
|
|
|
>>> b = Blog.objects.get(id=1)
|
|
>>> e = Entry.objects.get(id=234)
|
|
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
|
|
|
|
In the example above, in the case of a
|
|
:class:`~django.db.models.ForeignKey` relationship,
|
|
:meth:`QuerySet.update() <django.db.models.query.QuerySet.update>`
|
|
is used to perform the update. This requires the objects to already be
|
|
saved.
|
|
|
|
You can use the ``bulk=False`` argument to instead have the related
|
|
manager perform the update by calling ``e.save()``.
|
|
|
|
Using ``add()`` with a many-to-many relationship, however, will not
|
|
call any ``save()`` methods (the ``bulk`` argument doesn't exist), but
|
|
rather create the relationships using :meth:`QuerySet.bulk_create()
|
|
<django.db.models.query.QuerySet.bulk_create>`. If you need to execute
|
|
some custom logic when a relationship is created, listen to the
|
|
:data:`~django.db.models.signals.m2m_changed` signal, which will
|
|
trigger ``pre_add`` and ``post_add`` actions.
|
|
|
|
Using ``add()`` on a relation that already exists won't duplicate the
|
|
relation, but it will still trigger signals.
|
|
|
|
``add()`` also accepts the field the relation points to as an argument.
|
|
The above example can be rewritten as ``b.entry_set.add(234)``.
|
|
|
|
Use the ``through_defaults`` argument to specify values for the new
|
|
:ref:`intermediate model <intermediary-manytomany>` instance(s), if
|
|
needed.
|
|
|
|
.. versionchanged:: 2.2
|
|
|
|
The ``through_defaults`` argument was added.
|
|
|
|
.. method:: create(through_defaults=None, **kwargs)
|
|
|
|
Creates a new object, saves it and puts it in the related object set.
|
|
Returns the newly created object::
|
|
|
|
>>> b = Blog.objects.get(id=1)
|
|
>>> e = b.entry_set.create(
|
|
... headline='Hello',
|
|
... body_text='Hi',
|
|
... pub_date=datetime.date(2005, 1, 1)
|
|
... )
|
|
|
|
# No need to call e.save() at this point -- it's already been saved.
|
|
|
|
This is equivalent to (but simpler than)::
|
|
|
|
>>> b = Blog.objects.get(id=1)
|
|
>>> e = Entry(
|
|
... blog=b,
|
|
... headline='Hello',
|
|
... body_text='Hi',
|
|
... pub_date=datetime.date(2005, 1, 1)
|
|
... )
|
|
>>> e.save(force_insert=True)
|
|
|
|
Note that there's no need to specify the keyword argument of the model
|
|
that defines the relationship. In the above example, we don't pass the
|
|
parameter ``blog`` to ``create()``. Django figures out that the new
|
|
``Entry`` object's ``blog`` field should be set to ``b``.
|
|
|
|
Use the ``through_defaults`` argument to specify values for the new
|
|
:ref:`intermediate model <intermediary-manytomany>` instance, if
|
|
needed.
|
|
|
|
.. versionchanged:: 2.2
|
|
|
|
The ``through_defaults`` argument was added.
|
|
|
|
.. method:: remove(*objs, bulk=True)
|
|
|
|
Removes the specified model objects from the related object set::
|
|
|
|
>>> b = Blog.objects.get(id=1)
|
|
>>> e = Entry.objects.get(id=234)
|
|
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
|
|
|
|
Similar to :meth:`add()`, ``e.save()`` is called in the example above
|
|
to perform the update. Using ``remove()`` with a many-to-many
|
|
relationship, however, will delete the relationships using
|
|
:meth:`QuerySet.delete()<django.db.models.query.QuerySet.delete>` which
|
|
means no model ``save()`` methods are called; listen to the
|
|
:data:`~django.db.models.signals.m2m_changed` signal if you wish to
|
|
execute custom code when a relationship is deleted.
|
|
|
|
Similarly to :meth:`add()`, ``remove()`` also accepts the field the
|
|
relation points to as an argument. The above example can be rewritten
|
|
as ``b.entry_set.remove(234)``.
|
|
|
|
For :class:`~django.db.models.ForeignKey` objects, this method only
|
|
exists if ``null=True``. If the related field can't be set to ``None``
|
|
(``NULL``), then an object can't be removed from a relation without
|
|
being added to another. In the above example, removing ``e`` from
|
|
``b.entry_set()`` is equivalent to doing ``e.blog = None``, and because
|
|
the ``blog`` :class:`~django.db.models.ForeignKey` doesn't have
|
|
``null=True``, this is invalid.
|
|
|
|
For :class:`~django.db.models.ForeignKey` objects, this method accepts
|
|
a ``bulk`` argument to control how to perform the operation.
|
|
If ``True`` (the default), ``QuerySet.update()`` is used.
|
|
If ``bulk=False``, the ``save()`` method of each individual model
|
|
instance is called instead. This triggers the
|
|
:data:`~django.db.models.signals.pre_save` and
|
|
:data:`~django.db.models.signals.post_save` signals and comes at the
|
|
expense of performance.
|
|
|
|
For many-to-many relationships, the ``bulk`` keyword argument doesn't
|
|
exist.
|
|
|
|
.. method:: clear(bulk=True)
|
|
|
|
Removes all objects from the related object set::
|
|
|
|
>>> b = Blog.objects.get(id=1)
|
|
>>> b.entry_set.clear()
|
|
|
|
Note this doesn't delete the related objects -- it just disassociates
|
|
them.
|
|
|
|
Just like ``remove()``, ``clear()`` is only available on
|
|
:class:`~django.db.models.ForeignKey`\s where ``null=True`` and it also
|
|
accepts the ``bulk`` keyword argument.
|
|
|
|
For many-to-many relationships, the ``bulk`` keyword argument doesn't
|
|
exist.
|
|
|
|
.. method:: set(objs, bulk=True, clear=False, through_defaults=None)
|
|
|
|
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.
|
|
|
|
For :class:`~django.db.models.ForeignKey` objects, the ``bulk``
|
|
argument is passed on to :meth:`add` and :meth:`remove`.
|
|
|
|
For many-to-many relationships, the ``bulk`` keyword argument doesn't
|
|
exist.
|
|
|
|
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()``.
|
|
|
|
Similarly to :meth:`add()`, ``set()`` also accepts the field the
|
|
relation points to as an argument. The above example can be rewritten
|
|
as ``e.related_set.set([obj1.pk, obj2.pk, obj3.pk])``.
|
|
|
|
Use the ``through_defaults`` argument to specify values for the new
|
|
:ref:`intermediate model <intermediary-manytomany>` instance(s), if
|
|
needed.
|
|
|
|
.. versionchanged:: 2.2
|
|
|
|
The ``through_defaults`` argument was added.
|
|
|
|
.. note::
|
|
|
|
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.
|
|
|
|
If you use :meth:`~django.db.models.query.QuerySet.prefetch_related`,
|
|
the ``add()``, ``remove()``, ``clear()``, and ``set()`` methods clear
|
|
the prefetched cache.
|