| 1 |
""" |
|---|
| 2 |
20. Multiple many-to-many relationships between the same two tables |
|---|
| 3 |
|
|---|
| 4 |
In this example, an ``Article`` can have many "primary" ``Category`` objects |
|---|
| 5 |
and many "secondary" ``Category`` objects. |
|---|
| 6 |
|
|---|
| 7 |
Set ``related_name`` to designate what the reverse relationship is called. |
|---|
| 8 |
""" |
|---|
| 9 |
|
|---|
| 10 |
from django.db import models |
|---|
| 11 |
|
|---|
| 12 |
class Category(models.Model): |
|---|
| 13 |
name = models.CharField(max_length=20) |
|---|
| 14 |
class Meta: |
|---|
| 15 |
ordering = ('name',) |
|---|
| 16 |
|
|---|
| 17 |
def __unicode__(self): |
|---|
| 18 |
return self.name |
|---|
| 19 |
|
|---|
| 20 |
class Article(models.Model): |
|---|
| 21 |
headline = models.CharField(max_length=50) |
|---|
| 22 |
pub_date = models.DateTimeField() |
|---|
| 23 |
primary_categories = models.ManyToManyField(Category, related_name='primary_article_set') |
|---|
| 24 |
secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set') |
|---|
| 25 |
class Meta: |
|---|
| 26 |
ordering = ('pub_date',) |
|---|
| 27 |
|
|---|
| 28 |
def __unicode__(self): |
|---|
| 29 |
return self.headline |
|---|
| 30 |
|
|---|
| 31 |
__test__ = {'API_TESTS':""" |
|---|
| 32 |
>>> from datetime import datetime |
|---|
| 33 |
|
|---|
| 34 |
>>> c1 = Category(name='Sports') |
|---|
| 35 |
>>> c1.save() |
|---|
| 36 |
>>> c2 = Category(name='News') |
|---|
| 37 |
>>> c2.save() |
|---|
| 38 |
>>> c3 = Category(name='Crime') |
|---|
| 39 |
>>> c3.save() |
|---|
| 40 |
>>> c4 = Category(name='Life') |
|---|
| 41 |
>>> c4.save() |
|---|
| 42 |
|
|---|
| 43 |
>>> a1 = Article(headline='Area man steals', pub_date=datetime(2005, 11, 27)) |
|---|
| 44 |
>>> a1.save() |
|---|
| 45 |
>>> a1.primary_categories.add(c2, c3) |
|---|
| 46 |
>>> a1.secondary_categories.add(c4) |
|---|
| 47 |
|
|---|
| 48 |
>>> a2 = Article(headline='Area man runs', pub_date=datetime(2005, 11, 28)) |
|---|
| 49 |
>>> a2.save() |
|---|
| 50 |
>>> a2.primary_categories.add(c1, c2) |
|---|
| 51 |
>>> a2.secondary_categories.add(c4) |
|---|
| 52 |
|
|---|
| 53 |
>>> a1.primary_categories.all() |
|---|
| 54 |
[<Category: Crime>, <Category: News>] |
|---|
| 55 |
|
|---|
| 56 |
>>> a2.primary_categories.all() |
|---|
| 57 |
[<Category: News>, <Category: Sports>] |
|---|
| 58 |
|
|---|
| 59 |
>>> a1.secondary_categories.all() |
|---|
| 60 |
[<Category: Life>] |
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
>>> c1.primary_article_set.all() |
|---|
| 64 |
[<Article: Area man runs>] |
|---|
| 65 |
>>> c1.secondary_article_set.all() |
|---|
| 66 |
[] |
|---|
| 67 |
>>> c2.primary_article_set.all() |
|---|
| 68 |
[<Article: Area man steals>, <Article: Area man runs>] |
|---|
| 69 |
>>> c2.secondary_article_set.all() |
|---|
| 70 |
[] |
|---|
| 71 |
>>> c3.primary_article_set.all() |
|---|
| 72 |
[<Article: Area man steals>] |
|---|
| 73 |
>>> c3.secondary_article_set.all() |
|---|
| 74 |
[] |
|---|
| 75 |
>>> c4.primary_article_set.all() |
|---|
| 76 |
[] |
|---|
| 77 |
>>> c4.secondary_article_set.all() |
|---|
| 78 |
[<Article: Area man steals>, <Article: Area man runs>] |
|---|
| 79 |
"""} |
|---|