Django Community App Models – Complete Tutorial & Explanation
Django Community App Models – Complete Tutorial & Explanation
This Django app is designed for building online communities (like forums, study groups, interest-based groups, etc.), where users can:
- Create or join Communities
- Post content (posts, notes)
- Organize content into Collections
- Like posts and comment on them
- Manage members with roles (Admin, Moderator, Member)
1. Base Model (TimeStampedModel)
All main models inherit from TimeStampedModel (assumed to be in base.py).
# base.py
class TimeStampedModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
This automatically adds created_at and updated_at timestamps to every model that inherits from it.
2. Community Model – The Core of the App
This represents a community (e.g., "Python Developers", "Stock Market India", "Fitness Freaks", etc.)
class Community(TimeStampedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True, blank=True) # Used in URLs
description = models.TextField(blank=True)
# SEO Fields
meta_title = models.CharField(max_length=255, blank=True)
meta_description = models.TextField(blank=True)
meta_keywords = models.CharField(max_length=500, blank=True)
# Members
members = models.ManyToManyField(
settings.AUTH_USER_MODEL,
through="CommunityMembership",
related_name="community_memberships",
)
is_public = models.BooleanField(default=True) # Public or Private community
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True,
related_name="created_communities",
)
Key Features:
- Uses UUID as primary key (more secure than auto-increment ID)
- Auto-generates slug from name if not provided (with unique suffix)
- Auto-fills SEO fields if left blank
- Supports public/private communities
- Uses
throughmodel (CommunityMembership) for advanced membership management
3. Tag Model
Simple model to categorize posts.
class Tag(models.Model):
name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.name
Used for tagging posts (e.g., #python, #machinelearning, #interview).
4. CommunityPost Model – Main Content
This is where users create posts inside a community.
class CommunityPost(TimeStampedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
community = models.ForeignKey(Community, on_delete=models.CASCADE, related_name="community_posts")
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="community_posts")
title = models.CharField(max_length=255)
content = models.TextField()
slug = models.SlugField(max_length=200, unique=True, blank=True)
# SEO
meta_title = models.CharField(max_length=255, blank=True)
meta_description = models.TextField(blank=True)
# Tags
tags = models.ManyToManyField(Tag, blank=True, related_name="posts")
Key Points:
- Each post belongs to one community and one author.
- Auto-generates slug from title.
- Supports multiple tags.
- Has SEO fields for better search engine visibility.
5. CommunityNote Model
For sharing files + text notes (useful for study communities, project groups, etc.)
class CommunityNote(TimeStampedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
community = models.ForeignKey(Community, on_delete=models.CASCADE, related_name="community_notes")
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="community_notes")
title = models.CharField(max_length=255)
file = models.FileField(upload_to="notes/", blank=True, null=True)
content = models.TextField(blank=True)
Use case: Sharing PDF notes, assignments, research papers, etc.
6. CommunityCollection Model
Like a folder or playlist inside the community to organize content.
class CommunityCollection(TimeStampedModel):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
community = models.ForeignKey(Community, on_delete=models.CASCADE, related_name="community_collections")
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
posts = models.ManyToManyField(CommunityPost, blank=True, related_name="collection_posts")
notes = models.ManyToManyField(CommunityNote, blank=True, related_name="collection_notes")
Use case: "Best Python Resources", "Interview Preparation", "Weekly Reads", etc.
7. CommunityMembership Model – Role Management
This is the through model that connects User ↔ Community with roles.
class CommunityMembership(TimeStampedModel):
ROLE_CHOICES = (
("admin", "Admin"),
("moderator", "Moderator"),
("member", "Member"),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="memberships")
community = models.ForeignKey(Community, on_delete=models.CASCADE, related_name="memberships")
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default="member")
joined_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ("user", "community") # One user can join a community only once
Benefits:
- Supports different permissions (Admin can manage everything, Moderator can moderate, Member can only post/comment)
- Prevents duplicate memberships
8. PostLike Model
Simple like system (no timestamp needed).
class PostLike(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="liked_posts")
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE, related_name="likes")
class Meta:
unique_together = ("user", "post") # One user can like a post only once
9. Comment Model – Nested Comments
Supports threaded/reply comments.
class Comment(TimeStampedModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="comments")
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE, related_name="comments")
content = models.TextField()
parent = models.ForeignKey(
"self",
null=True,
blank=True,
on_delete=models.CASCADE,
related_name="replies"
)
How nested comments work:
- If
parentisNone→ Top-level comment - If
parenthas a value → This is a reply to another comment
Summary of Relationships
| Model | Relationship Type | Connected To |
|---|---|---|
| Community | ManyToMany (through) | User (members) |
| CommunityPost | ForeignKey | Community, User |
| CommunityNote | ForeignKey | Community, User |
| CommunityCollection | ManyToMany | CommunityPost, CommunityNote |
| CommunityMembership | ForeignKey | User, Community |
| PostLike | ManyToMany style | User ↔ CommunityPost |
| Comment | Self-referential | Comment (for replies) |
Best Practices Used in This Code
- UUID as primary key (better for scalability & security)
- Auto slug generation with uniqueness
- Auto SEO field population
- Proper use of
related_name unique_togetherto prevent duplicatesthroughmodel for advanced many-to-many- Clean
__str__methods - Proper indexing for performance
Would you like me to also create:
- Admin.py configuration for all these models?
- Views & URLs structure tutorial?
- Serializers (for Django REST Framework)?
- Permissions logic based on roles?
Just tell me what you need next!