1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
=========================
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)
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(obj1, [obj2, ...])
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,
``e.save()`` is called by the related manager to perform the update.
Using ``add()`` with a many-to-many relationship, however, will not
call any ``save()`` methods, 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.
.. method:: create(**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 much 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``.
.. method:: remove(obj1, [obj2, ...])
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.
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.
.. versionchanged 1.7::
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.
.. method:: clear()
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.
.. 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.
Also, if you are using :ref:`an intermediate model
<intermediary-manytomany>` for a many-to-many relationship, some of the
related manager's methods are disabled.
.. _direct-assignment:
Direct Assignment
-----------------
A related object set can be replaced in bulk with one operation by assigning a
new iterable of objects to it::
>>> new_list = [obj1, obj2, obj3]
>>> 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.
|