Best examples of examples of Django model relationships example in real projects
Starting with real examples of Django model relationships
Let’s skip theory and jump straight into concrete code. The best examples of Django model relationships all come from the same place: problems you actually hit in production.
Below are several examples of examples of Django model relationships example patterns you’ll see over and over:
- A blog with posts and comments
- An ecommerce store with products, orders, and order items
- A SaaS app with users, profiles, and subscriptions
- A social feature with followers and likes
- A tagging system that stays flexible over time
- A multi-tenant setup where data is scoped to an organization
Each one leans on a different relationship type: ForeignKey, ManyToManyField, and OneToOneField, plus some advanced tricks that use through models and constraints.
Blog: classic ForeignKey one-to-many example of Post → Comment
This is usually the first relationship you write in Django, and it’s still one of the best examples of how simple the ORM can be.
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
title = models.CharField(max_length=200)
body = models.TextField()
published_at = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Comment by {self.author or 'Anonymous'} on {self.post}"
Why this matters in 2024–2025:
related_nameis non-negotiable if you care about readable code and avoiding clashes.- Using
get_user_model()instead ofauth.Userkeeps you compatible with custom user models, which are now the norm in modern Django projects.
This is a clean example of a one-to-many relationship: one Post has many Comment objects; each Comment belongs to exactly one Post.
Ecommerce: the best examples of many-to-one and one-to-many combined
Real ecommerce schemas are a gold mine of examples of Django model relationships. You almost always end up with an Order that contains multiple OrderItem rows, each tied to a Product.
class Product(models.Model):
name = models.CharField(max_length=200)
sku = models.CharField(max_length=50, unique=True)
price_cents = models.PositiveIntegerField()
def __str__(self):
return self.name
class Order(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="orders")
created_at = models.DateTimeField(auto_now_add=True)
paid = models.BooleanField(default=False)
def __str__(self):
return f"Order #{self.id} for {self.customer}"
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items")
product = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="order_items")
quantity = models.PositiveIntegerField(default=1)
unit_price_cents = models.PositiveIntegerField()
def line_total_cents(self):
return self.quantity * self.unit_price_cents
This gives you two clear examples of one-to-many relationships:
- One
Order→ manyOrderItemrows - One
Product→ manyOrderItemrows across different orders
Design choices worth copying:
on_delete=models.PROTECTonProductandcustomerprevents accidental data loss.- Storing
unit_price_centsonOrderItemfreezes the price at purchase time, which matches how real payment systems behave.
If you’re curious about how production-grade ecommerce deals with data integrity, payment providers like Stripe discuss similar modeling patterns in their docs: https://stripe.com/docs (not .gov/.edu, but highly relevant reading).
Many-to-many with extra data: tagging as a real example of a through model
Plain ManyToManyField is fine when you only care that two things are linked. But real apps often need extra metadata on the relationship itself. Tagging is one of the best examples of that.
class Tag(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
tags = models.ManyToManyField(Tag, through="ArticleTag", related_name="articles")
def __str__(self):
return self.title
class ArticleTag(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
unique_together = ("article", "tag")
This is a textbook example of using through to store relationship-level data. You get:
- When the tag was added
- Who added it
- A guarantee that an article–tag pair only appears once (
unique_together)
In 2024–2025, you might replace unique_together with UniqueConstraint for more explicit naming and better migrations:
from django.db.models import UniqueConstraint
class ArticleTag(models.Model):
# # fields as above
class Meta:
constraints = [
UniqueConstraint(fields=["article", "tag"], name="uniq_article_tag_pair"),
]
This pattern scales well and is one of the best examples of a flexible design you won’t regret later.
One-to-one: profile and user, a real example from almost every SaaS app
If you need extra per-user data but want a clean separation from authentication, OneToOneField is your friend.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
timezone = models.CharField(max_length=50, default="UTC")
marketing_opt_in = models.BooleanField(default=False)
def __str__(self):
return f"Profile for {self.user}"
This is a straightforward example of a one-to-one relationship:
- Every
Userhas at most oneProfile. - Every
Profilebelongs to exactly oneUser.
Why teams still use this pattern heavily in 2024–2025:
- It keeps your authentication model lean and focused.
- It lets you split concerns across apps (
accounts,billing,profiles) without massive migrations.
If you’re modeling sensitive user data (health, education, etc.), you’ll also want to read up on privacy and security best practices. For example, the U.S. Department of Health & Human Services has solid guidance on handling protected health information: https://www.hhs.gov/hipaa/index.html.
Subscriptions: examples include plan history and soft one-to-many
Modern SaaS billing is a rich source of examples of Django model relationships. You usually need to track subscription plans over time, not just the current one.
class Plan(models.Model):
name = models.CharField(max_length=100)
price_cents = models.PositiveIntegerField()
interval = models.CharField(max_length=10, choices=[("month", "Month"), ("year", "Year")])
def __str__(self):
return f"{self.name} ({self.interval})"
class Subscription(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="subscriptions")
plan = models.ForeignKey(Plan, on_delete=models.PROTECT, related_name="subscriptions")
started_at = models.DateTimeField()
ended_at = models.DateTimeField(null=True, blank=True)
@property
def is_active(self):
return self.ended_at is None
Here, examples include:
- A user with multiple
Subscriptionrows over time (plan upgrades, downgrades, cancellations). - A
Planused by many subscriptions, but protected from deletion.
This pattern plays nicely with external billing providers and analytics because you never lose history. It’s a very practical example of designing for time-based data, which matters a lot more now that teams care about churn and cohort analysis.
Social features: followers and likes as many-to-many real examples
Social graphs are another set of examples of Django model relationships that show up in dashboards, communities, and internal tools.
Followers: self-referential many-to-many
class SocialProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="social_profile")
bio = models.CharField(max_length=160, blank=True)
followers = models.ManyToManyField(
"self",
symmetrical=False,
related_name="following",
through="Follow",
)
class Follow(models.Model):
follower = models.ForeignKey(SocialProfile, on_delete=models.CASCADE, related_name="following_rel")
followed = models.ForeignKey(SocialProfile, on_delete=models.CASCADE, related_name="followers_rel")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=["follower", "followed"], name="uniq_follow_pair"),
models.CheckConstraint(
check=~models.Q(follower=models.F("followed")),
name="prevent_self_follow",
),
]
This is one of the best examples of a self-referential many-to-many relationship with extra data and constraints.
Likes: many-to-many to content
class PostLike(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="post_likes")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="likes")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ("user", "post")
You could use a ManyToManyField with through=PostLike, but keeping it explicit is often clearer in larger codebases.
Multi-tenant data: organization-scoped relationships example
As more teams ship SaaS products, multi-tenancy has become a default concern. That makes it a great place to look for examples of examples of Django model relationships example patterns that scale.
class Organization(models.Model):
name = models.CharField(max_length=200)
owner = models.ForeignKey(User, on_delete=models.PROTECT, related_name="owned_organizations")
def __str__(self):
return self.name
class Membership(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="memberships")
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="memberships")
role = models.CharField(max_length=50, default="member")
class Meta:
unique_together = ("user", "organization")
class Project(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="projects")
name = models.CharField(max_length=200)
def __str__(self):
return self.name
Here, examples include:
- Users belonging to multiple organizations (
Membershipas a many-to-many through model). - Projects scoped to a single
OrganizationviaForeignKey.
This structure keeps data isolation clear and is one of the best examples of a pattern that works for everything from analytics tools to internal CRMs.
Performance and query patterns for these Django relationship examples
All these examples of Django model relationships share a common performance story:
- Use
select_relatedfor one-to-one and many-to-one (foreign keys) when you know you’ll need the related object. - Use
prefetch_relatedfor many-to-many and reverse foreign keys.
## Example: fetching posts with authors and comments efficiently
posts = (
Post.objects
.select_related("author")
.prefetch_related("comments__author")
)
In 2024–2025, Django’s ORM has matured to the point where you can push quite far with these tools before reaching for raw SQL. For deeper reading on relational modeling and query optimization, classic database texts from universities still hold up well. For example, MIT’s open courseware on databases is a solid reference: https://ocw.mit.edu/courses/6-830-database-systems-fall-2010/
FAQ: short answers with more examples
What are some common examples of Django model relationships in real apps?
Common examples of Django model relationships include:
Post→Commentwith aForeignKeyOrder→OrderItemfor ecommerceUser→Profilewith aOneToOneFieldArticle↔Tagvia aManyToManyFieldand athroughmodelOrganization↔Uservia aMembershipmodel
All of these are real examples you can adapt directly.
Can you give an example of when to use ManyToManyField vs a separate model?
Use a plain ManyToManyField when you only care that two records are linked, like a User subscribing to Newsletter topics. If you need extra data on the relationship (timestamps, roles, flags), use a separate model with ForeignKey fields and either declare it as through= or treat it explicitly, as in the ArticleTag and Membership examples above.
What is a good example of a one-to-one relationship besides user profiles?
A strong example of a one-to-one relationship is splitting sensitive data from a main record. For instance, Patient and PatientMedicalRecord in a health app, where the medical record is tightly controlled and audited separately. Health-focused organizations like the NIH discuss data separation and privacy in their research guidance: https://www.nih.gov/health-information.
How do these examples of Django model relationships scale as my app grows?
These patterns scale well as long as you:
- Add indexes on foreign keys and frequently filtered fields.
- Use
select_relatedandprefetch_relatedto avoid N+1 queries. - Keep write-heavy models smaller and push archival data into separate tables when needed.
If you follow the best examples shown here—clear related_names, explicit on_delete behavior, and thoughtful constraints—you can grow from a side project to a serious production system without constantly rewriting your schema.
Related Topics
Best examples of Django template rendering examples in real projects
Best examples of Django static files example: practical guide for 2025
Best examples of examples of Django model relationships example in real projects
Real-World Examples of Django REST Framework Examples for 2025
Real-world examples of examples of Django middleware example patterns
Practical examples of Django authentication examples for beginners
Explore More Django Code Snippets
Discover more examples and insights in this category.
View All Django Code Snippets