Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

documented RelatedManager calling save() behind the scenes, added sec…

…tion on direct replacement of related object set
  • Loading branch information...
commit a5bcc09c8f2b0c1cc06a6039a700fbf6103656f7 1 parent a91799a
authored September 06, 2013

Showing 1 changed file with 92 additions and 64 deletions. Show diff stats Hide diff stats

  1. 156  docs/ref/models/relations.txt
156  docs/ref/models/relations.txt
@@ -36,89 +36,117 @@ Related objects reference
36 36
       In this example, the methods below will be available both on
37 37
       ``topping.pizza_set`` and on ``pizza.toppings``.
38 38
 
39  
-    These related managers have some extra methods:
  39
+.. _related-manager-methods:
40 40
 
41  
-    .. method:: add(obj1, [obj2, ...])
  41
+Related Manager Methods
  42
+-----------------------
42 43
 
43  
-        Adds the specified model objects to the related object set.
  44
+.. method:: add(obj1, [obj2, ...])
44 45
 
45  
-        Example::
  46
+    Adds the specified model objects to the related object set.
46 47
 
47  
-            >>> b = Blog.objects.get(id=1)
48  
-            >>> e = Entry.objects.get(id=234)
49  
-            >>> b.entry_set.add(e) # Associates Entry e with Blog b.
  48
+    Example::
50 49
 
51  
-        In the example above, ``e.save()`` is called to perform the update.
52  
-        Using ``add()`` with a many-to-many relationship, however, will not
53  
-        call any ``save()`` methods, but rather create the relationships
54  
-        using :meth:`QuerySet.bulk_create()
55  
-        <django.db.models.query.QuerySet.bulk_create>`. If you need to execute
56  
-        some custom logic when a relationship is created, listen to the
57  
-        :data:`~django.db.models.signals.m2m_changed` signal.
  50
+        >>> b = Blog.objects.get(id=1)
  51
+        >>> e = Entry.objects.get(id=234)
  52
+        >>> b.entry_set.add(e) # Associates Entry e with Blog b.
58 53
 
59  
-    .. method:: create(**kwargs)
  54
+    In the example above, in the case of a
  55
+    :class:`~django.db.models.ForeignKey` relationship,
  56
+    ``e.save()`` is called by the related manager to perform the update.
  57
+    Using ``add()`` with a many-to-many relationship, however, will not
  58
+    call any ``save()`` methods, but rather create the relationships
  59
+    using :meth:`QuerySet.bulk_create()
  60
+    <django.db.models.query.QuerySet.bulk_create>`. If you need to execute
  61
+    some custom logic when a relationship is created, listen to the
  62
+    :data:`~django.db.models.signals.m2m_changed` signal.
60 63
 
61  
-        Creates a new object, saves it and puts it in the related object set.
62  
-        Returns the newly created object::
  64
+.. method:: create(**kwargs)
63 65
 
64  
-            >>> b = Blog.objects.get(id=1)
65  
-            >>> e = b.entry_set.create(
66  
-            ...     headline='Hello',
67  
-            ...     body_text='Hi',
68  
-            ...     pub_date=datetime.date(2005, 1, 1)
69  
-            ... )
  66
+    Creates a new object, saves it and puts it in the related object set.
  67
+    Returns the newly created object::
70 68
 
71  
-            # No need to call e.save() at this point -- it's already been saved.
  69
+        >>> b = Blog.objects.get(id=1)
  70
+        >>> e = b.entry_set.create(
  71
+        ...     headline='Hello',
  72
+        ...     body_text='Hi',
  73
+        ...     pub_date=datetime.date(2005, 1, 1)
  74
+        ... )
72 75
 
73  
-        This is equivalent to (but much simpler than)::
  76
+        # No need to call e.save() at this point -- it's already been saved.
74 77
 
75  
-            >>> b = Blog.objects.get(id=1)
76  
-            >>> e = Entry(
77  
-            ...     blog=b,
78  
-            ...     headline='Hello',
79  
-            ...     body_text='Hi',
80  
-            ...     pub_date=datetime.date(2005, 1, 1)
81  
-            ... )
82  
-            >>> e.save(force_insert=True)
  78
+    This is equivalent to (but much simpler than)::
83 79
 
84  
-        Note that there's no need to specify the keyword argument of the model
85  
-        that defines the relationship. In the above example, we don't pass the
86  
-        parameter ``blog`` to ``create()``. Django figures out that the new
87  
-        ``Entry`` object's ``blog`` field should be set to ``b``.
  80
+        >>> b = Blog.objects.get(id=1)
  81
+        >>> e = Entry(
  82
+        ...     blog=b,
  83
+        ...     headline='Hello',
  84
+        ...     body_text='Hi',
  85
+        ...     pub_date=datetime.date(2005, 1, 1)
  86
+        ... )
  87
+        >>> e.save(force_insert=True)
88 88
 
89  
-    .. method:: remove(obj1, [obj2, ...])
  89
+    Note that there's no need to specify the keyword argument of the model
  90
+    that defines the relationship. In the above example, we don't pass the
  91
+    parameter ``blog`` to ``create()``. Django figures out that the new
  92
+    ``Entry`` object's ``blog`` field should be set to ``b``.
90 93
 
91  
-        Removes the specified model objects from the related object set::
  94
+.. method:: remove(obj1, [obj2, ...])
92 95
 
93  
-            >>> b = Blog.objects.get(id=1)
94  
-            >>> e = Entry.objects.get(id=234)
95  
-            >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
  96
+    Removes the specified model objects from the related object set::
96 97
 
97  
-        Similar to :meth:`add()`, ``e.save()`` is called in the example above
98  
-        to perform the update. Using ``remove()`` with a many-to-many
99  
-        relationship, however, will delete the relationships using
100  
-        :meth:`QuerySet.delete()<django.db.models.query.QuerySet.delete>` which
101  
-        means no model ``save()`` methods are called; listen to the
102  
-        :data:`~django.db.models.signals.m2m_changed` signal if you wish to
103  
-        execute custom code when a relationship is deleted.
  98
+        >>> b = Blog.objects.get(id=1)
  99
+        >>> e = Entry.objects.get(id=234)
  100
+        >>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
104 101
 
105  
-        For :class:`~django.db.models.ForeignKey` objects, this method only
106  
-        exists if ``null=True``. If the related field can't be set to ``None``
107  
-        (``NULL``), then an object can't be removed from a relation without
108  
-        being added to another. In the above example, removing ``e`` from
109  
-        ``b.entry_set()`` is equivalent to doing ``e.blog = None``, and because
110  
-        the ``blog`` :class:`~django.db.models.ForeignKey` doesn't have
111  
-        ``null=True``, this is invalid.
  102
+    Similar to :meth:`add()`, ``e.save()`` is called in the example above
  103
+    to perform the update. Using ``remove()`` with a many-to-many
  104
+    relationship, however, will delete the relationships using
  105
+    :meth:`QuerySet.delete()<django.db.models.query.QuerySet.delete>` which
  106
+    means no model ``save()`` methods are called; listen to the
  107
+    :data:`~django.db.models.signals.m2m_changed` signal if you wish to
  108
+    execute custom code when a relationship is deleted.
112 109
 
113  
-    .. method:: clear()
  110
+    For :class:`~django.db.models.ForeignKey` objects, this method only
  111
+    exists if ``null=True``. If the related field can't be set to ``None``
  112
+    (``NULL``), then an object can't be removed from a relation without
  113
+    being added to another. In the above example, removing ``e`` from
  114
+    ``b.entry_set()`` is equivalent to doing ``e.blog = None``, and because
  115
+    the ``blog`` :class:`~django.db.models.ForeignKey` doesn't have
  116
+    ``null=True``, this is invalid.
114 117
 
115  
-        Removes all objects from the related object set::
  118
+.. method:: clear()
116 119
 
117  
-            >>> b = Blog.objects.get(id=1)
118  
-            >>> b.entry_set.clear()
  120
+    Removes all objects from the related object set::
119 121
 
120  
-        Note this doesn't delete the related objects -- it just disassociates
121  
-        them.
  122
+        >>> b = Blog.objects.get(id=1)
  123
+        >>> b.entry_set.clear()
122 124
 
123  
-        Just like ``remove()``, ``clear()`` is only available on
124  
-        :class:`~django.db.models.ForeignKey`\s where ``null=True``.
  125
+    Note this doesn't delete the related objects -- it just disassociates
  126
+    them.
  127
+
  128
+    Just like ``remove()``, ``clear()`` is only available on
  129
+    :class:`~django.db.models.ForeignKey`\s where ``null=True``.
  130
+
  131
+.. note::
  132
+
  133
+   Note that ``add()``, ``create()``, ``remove()``, and ``clear()`` all
  134
+   apply database changes immediately for all types of related fields. In other
  135
+   words, there is no need to call ``save()`` on either end of the
  136
+   relationship.
  137
+
  138
+.. _direct-assignment:
  139
+
  140
+Direct Assignment
  141
+-----------------
  142
+
  143
+A related object set can be replaced in bulk with one operation by assigning a
  144
+new iterable of objects to it::
  145
+
  146
+    >>> new_list = [obj1, obj2, obj3]
  147
+    >>> e.related_set = new_list 
  148
+
  149
+If the foreign key relationship has ``null=True``, then the related manager
  150
+will first call ``clear()`` to disassociate any existing objects in the related
  151
+set before adding the contents of ``new_list``. Otherwise the objects in
  152
+``new_list`` will be added to the existing related object set.

0 notes on commit a5bcc09

Please sign in to comment.
Something went wrong with that request. Please try again.