#

## Django documentation

# 5. Many-to-many relationships

To define a many-to-many relationship, use ManyToManyField().

In this example, an article can be published in multiple publications, and a publication has multiple articles.

## Model source code

    from django.core import meta

    class Publication(meta.Model):
        title = meta.CharField(maxlength=30)

        def __repr__(self):
            return self.title

    class Article(meta.Model):
        headline = meta.CharField(maxlength=100)
        publications = meta.ManyToManyField(Publication)

        def __repr__(self):
            return self.headline

## API reference

### Publication objects have the following methods:

- `delete()`
- `get_article()`
- `get_article_count()`
- `get_article_list()`
- `save()`
- `set_articles()`

### Article objects have the following methods:

- `delete()`
- `get_publication_list()`
- `save()`
- `set_publications()`

## Sample API usage

This sample code assumes the above models have been saved in a file `examplemodel.py`.

    >>> from django.models.examplemodel import publications, articles

    # Create a couple of Publications.
    >>> p1 = publications.Publication(id=None, title='The Python Journal')
    >>> p1.save()
    >>> p2 = publications.Publication(id=None, title='Science News')
    >>> p2.save()

    # Create an Article.
    >>> a1 = articles.Article(id=None, headline='Django lets you build Web apps easily')
    >>> a1.save()

    # Associate the Article with one Publication. set_publications() returns a
    # boolean, representing whether any records were added or deleted.
    >>> a1.set_publications([p1.id])
    True

    # If we set it again, it'll return False, because the list of Publications
    # hasn't changed.
    >>> a1.set_publications([p1.id])
    False

    # Create another Article, and set it to appear in both Publications.
    >>> a2 = articles.Article(id=None, headline='NASA uses Python')
    >>> a2.save()
    >>> a2.set_publications([p1.id, p2.id])
    True
    >>> a2.set_publications([p1.id])
    True
    >>> a2.set_publications([p1.id, p2.id])
    True

    # Article objects have access to their related Publication objects.
    >>> a1.get_publication_list()
    [The Python Journal]
    >>> a2.get_publication_list()
    [The Python Journal, Science News]

    # Publication objects have access to their related Article objects.
    >>> p2.get_article_list()
    [NASA uses Python]
    >>> p1.get_article_list(order_by=['headline'])
    [Django lets you build Web apps easily, NASA uses Python]

    # If we delete a Publication, its Articles won't be able to access it.
    >>> p1.delete()
    >>> publications.get_list()
    [Science News]
    >>> a1 = articles.get_object(pk=1)
    >>> a1.get_publication_list()
    []

    # If we delete an Article, its Publications won't be able to access it.
    >>> a2.delete()
    >>> articles.get_list()
    [Django lets you build Web apps easily]
    >>> p1.get_article_list(order_by=['headline'])
    [Django lets you build Web apps easily]

## Comments

### stanko September 11, 2005 at 11:01 p.m.

If I have declare explicitly primary keys ex. article_id and publication_id then p1.get_article_list() fails

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "C:\Python23\lib\site-packages\django\utils\functional.py", line 3, in _curried
return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items()))
File "C:\Python23\lib\site-packages\django\core\meta\__init__.py", line 951, in method_get_related_many_to_many
kwargs['%s__id__exact' % rel_field.name] = self.id
AttributeError: 'Publication' object has no attribute 'id'

## Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: