Many-to-Many Relationships
In this page:
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.
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.
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.
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. #}
- Adding a ManyToManyField to both models instead of just one — it only needs to be declared once, on either side.
- Trying to assign related objects with = instead of using .add(), .set(), or .remove() on the manager.
- Forgetting that ManyToManyField changes are saved immediately when you call .add()/.remove(), without needing tutorial.save().
- 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.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: