Code

Ticket #6095: docs.3.diff

File docs.3.diff, 3.2 KB (added by floguy, 6 years ago)

Tried to rewrite the docs to be more user-centric instead of django-centric.

Line 
1diff --git a/docs/model-api.txt b/docs/model-api.txt
2index 3f908ec..d6c1719 100644
3--- a/docs/model-api.txt
4+++ b/docs/model-api.txt
5@@ -976,6 +976,75 @@ the relationship should work. All are optional:
6 
7     =======================  ============================================================
8 
9+Extra data on many-to-many relationships
10+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11+
12+When you're only dealing with mixing and matching pizzas and toppings, a standard
13+``ManyToManyField`` works great.  For many situations, however, some extra data
14+is necessary about relationships between models.  For situations like this,
15+Django allows for the specification of an intermediary many-to-many model.  To
16+use this functionality, specify a ``through`` keyword argument onto the
17+``ManyToManyField``.  This is best illustrated with an example::
18+
19+    class Person(models.Model):
20+        # ...
21+        name = models.CharField(max_length=128)
22+       
23+        def __unicode__(self):
24+            return self.name
25+   
26+    class Group(models.Model):
27+        # ...
28+        name = models.CharField(max_length=128)
29+        members = models.ManyToManyField(Person, through='Membership')
30+       
31+        def __unicode__(self):
32+            return self.name
33+   
34+    class Membership(models.Model):
35+        person = models.ForeignKey(Person)
36+        group = models.ForeignKey(Group)
37+        date_joined = models.DateTimeField()
38+        invite_reason = models.CharField(max_length=64)
39+
40+Now that you have set up your ``ManyToManyField`` to use your intermediary
41+model (Membership, in this case), you're ready to use the convenience methods
42+provided by that ``ManyToManyField``.  Here's an example of how you can query
43+for and use these models::
44+   
45+    >>> ringo = Person.objects.create(name="Ringo Starr")
46+    >>> paul = Person.objects.create(name="Paul McCartney")
47+    >>> beatles = Group.objects.create(name="The Beatles")
48+    >>> m1 = Membership.objects.create(person=ringo, group=beatles,
49+    ...     date_joined=datetime(1962, 8, 16),
50+    ...     invite_reason= "Needed a new drummer.")
51+    >>> beatles.members.all()
52+    [<Person: Ringo Starr>]
53+    >>> ringo.group_set.all()
54+    [<Group: The Beatles>]
55+    >>> m2 = Membership.objects.create(person=paul, group=beatles,
56+    ...     date_joined=datetime(1960, 8, 1),
57+    ...     invite_reason= "Wanted to form a band.")
58+    >>> beatles.members.all()
59+    [<Person: Ringo Starr>, <Person: Paul McCartney>]
60+
61+As you can see, creating ``Membership`` objects automatically adds the
62+``Person`` objects to the ``beatles.members`` queryset.  This means that you
63+can do anyting that you would do on a normal queryset, like ``filter`` or
64+``exclude``.
65+
66+.. note::
67+
68+    As soon as an intermediary model is specified, the ``add`` and 
69+    ``remove`` methods become unavailable on the descriptors added by the
70+    ``ManyToManyField``.  For example, something like 
71+    ``beatles.members.add(paul)`` will no longer work.
72+
73+For more examples and ideas on how to work with intermediary models, 
74+`see the tests`_.
75+
76+.. _`see the tests`: http://code.djangoproject.com/browser/django/trunk/tests/modeltests/m2m_manual/models.py
77+
78 One-to-one relationships
79 ~~~~~~~~~~~~~~~~~~~~~~~~
80