← Back to Django Course | Chapter 6: Advanced ORM Queries | Lesson 7 of 9

Many-to-Many Relationships

A many-to-many relationship is like students and clubs — one student can join many clubs, and one club can have many students.

Modeling Many-to-Many

A ManyToManyField declared on one model automatically gives both models a way to relate to multiple rows of the other.

Example: Modeling Many-to-Many

Each Tutorial can have many Tag objects, and each Tag can be linked to many Tutorial objects.

markup
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=50)

class Tutorial(models.Model):
    title = models.CharField(max_length=200)
    tags = models.ManyToManyField(Tag, related_name='tutorials')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Adding and Removing Relations

Because a ManyToManyField manages a set of relations, you use manager methods instead of plain assignment.

Example: Adding and Removing Relations

add() links the tag to the tutorial immediately; remove() unlinks it — both write to the hidden join table right away.

markup
from core.models import Tag

tutorial = Tutorial.objects.first()
tag = Tag.objects.get(name='beginner')

tutorial.tags.add(tag)
tutorial.tags.remove(tag)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Querying Across a Many-to-Many Field

You can filter through a ManyToManyField just like a ForeignKey, using double underscores to reach the related model's fields.

Example: Querying Across a Many-to-Many Field

This joins through the hidden many-to-many table to find every Tutorial linked to a Tag named beginner.

markup
from core.models import Tutorial

# Tutorials tagged 'beginner'
Tutorial.objects.filter(tags__name='beginner')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Adding a ManyToManyField to both models instead of just one — it only needs to be declared once, on either side.
  2. Trying to assign related objects with = instead of using .add(), .set(), or .remove() on the manager.
  3. Forgetting that ManyToManyField changes are saved immediately when you call .add()/.remove(), without needing tutorial.save().
Chapter Summary
  • ManyToManyField lets rows on both sides relate to multiple rows on the other side.
  • Django creates a hidden join table behind the scenes to store the relationships.
  • Use .add(), .remove(), and .set() to manage the relationship, not direct assignment.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.