Model Relationships — ManyToMany & OneToOne
ManyToManyField creates many-to-many relationships (posts have many tags, tags have many posts). OneToOneField creates one-to-one relationships (one user has one profile). Django handles the join tables automatically for ManyToMany.
20 min•By Priygop Team•Updated 2026
ManyToMany & OneToOne
- ManyToManyField — Creates a join table automatically
- Add/remove: post.tags.add(tag) / post.tags.remove(tag)
- Query: post.tags.all() / tag.posts.all()
- through=Model — Custom join table with extra fields
- OneToOneField — Like ForeignKey with unique=True
- Use OneToOne for extending models (User -> Profile)
- Access: user.profile / profile.user
Relationships Example
Relationships Example
# blog/models.py
# class Tag(models.Model):
# name = models.CharField(max_length=50, unique=True)
# slug = models.SlugField(unique=True)
# def __str__(self):
# return self.name
# class Post(models.Model):
# title = models.CharField(max_length=200)
# # ManyToMany — Posts <-> Tags
# tags = models.ManyToManyField(Tag, related_name='posts', blank=True)
# Usage:
# post = Post.objects.get(pk=1)
# tag = Tag.objects.get(name='python')
# post.tags.add(tag) # Add tag to post
# post.tags.remove(tag) # Remove tag
# post.tags.all() # All tags for post
# tag.posts.all() # All posts with this tag
# OneToOne — User Profile
# class Profile(models.Model):
# user = models.OneToOneField(
# User,
# on_delete=models.CASCADE,
# related_name='profile'
# )
# bio = models.TextField(blank=True)
# avatar = models.ImageField(upload_to='avatars/', blank=True)
# website = models.URLField(blank=True)
# Usage:
# user.profile.bio # Access profile from user
# profile.user.username # Access user from profileTip
Tip
Use Q objects for OR queries and F() for field-to-field comparisons. Aggregate with Count, Avg, Sum for statistics.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Python filtering on QuerySets instead of database filtering. Loop + if is slower than .filter() in the database.
Practice Task
Note
(1) Use Q objects for OR queries. (2) Use F() for field comparisons. (3) Aggregate with Count, Avg, Sum.
Quick Quiz
Key Takeaways
- ManyToManyField creates many-to-many relationships (posts have many tags, tags have many posts).
- ManyToManyField — Creates a join table automatically
- Add/remove: post.tags.add(tag) / post.tags.remove(tag)
- Query: post.tags.all() / tag.posts.all()