One-to-Many Relationships
Modeling One-to-Many
One-to-many means one row on one side can relate to many rows on the other side — implemented by putting a ForeignKey on the many model.
Example: Modeling One-to-Many
One Chapter can be the parent of many Tutorial rows, each pointing back to it through the chapter field.
from django.db import models
class Chapter(models.Model):
title = models.CharField(max_length=200)
class Tutorial(models.Model):
chapter = models.ForeignKey(
Chapter, related_name='tutorials', on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
{# 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. #}
Looking Up Children from the Parent
related_name gives you a friendly way to go from the one side back to all its related many rows.
Note: Without related_name, Django defaults to modelname_set, like chapter.tutorial_set.all().
Example: Looking Up Children from the Parent
Because related_name=tutorials was set on the ForeignKey, chapter.tutorials.all() returns every Tutorial linked to this chapter.
from core.models import Chapter
chapter = Chapter.objects.first()
chapter.tutorials.all()
{# 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. #}
on_delete Behavior
on_delete tells Django what to do to child rows when their parent is deleted — CASCADE deletes them too, SET_NULL clears the link instead.
Warning: Choosing CASCADE by default can silently delete more data than intended.
Example: on_delete Behavior
If the related Chapter is deleted, this Tutorial's chapter field becomes null instead of the Tutorial itself being deleted.
from django.db import models
class Tutorial(models.Model):
chapter = models.ForeignKey(
'Chapter', null=True, on_delete=models.SET_NULL
)
{# 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. #}
- Thinking the many side needs a ManyToManyField instead of a plain ForeignKey — a ForeignKey on the many model is enough.
- Forgetting the reverse accessor name (default is modelname_set, e.g. chapter.tutorial_set) or the custom related_name if one was set.
- Not choosing an appropriate on_delete behavior, leaving CASCADE by accident when SET_NULL was intended.
- One-to-many is modeled with a single ForeignKey on the many side.
- The one side can look up all its related rows using the reverse relation, e.g. chapter.tutorials.all().
- on_delete controls what happens to child rows when the parent is deleted.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: