Community App – Views, URLs & SEO Meta Setup
Tech3Space13 Apr 2026
Community App – Views, URLs & SEO Meta Setup
A complete guide to Views, URLs, and Meta Title/Description/Keywords for the Django Community Application using Django REST Framework.
1. Views (community/views.py)
from rest_framework import generics, permissions
from django.shortcuts import get_object_or_404
from .models import (
Community, CommunityPost, Comment, CommunityMembership
)
from .serializers import (
CommunityListSerializer,
CommunityDetailSerializer,
CommunityPostListSerializer,
CommunityPostDetailSerializer,
CommunityPostCreateSerializer,
CommentSerializer,
CommentCreateSerializer,
CommunityMembershipSerializer,
)
# ====================== Community Views ======================
class CommunityListCreateView(generics.ListCreateAPIView):
"""List all public communities or create a new one"""
queryset = Community.objects.filter(is_public=True).select_related('created_by')
serializer_class = CommunityListSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
class CommunityDetailView(generics.RetrieveUpdateDestroyAPIView):
"""Retrieve, update or delete a community"""
queryset = Community.objects.select_related('created_by')
serializer_class = CommunityDetailSerializer
lookup_field = 'slug'
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
# ====================== Community Post Views ======================
class CommunityPostListCreateView(generics.ListCreateAPIView):
"""List posts in a community or create a new post"""
serializer_class = CommunityPostListSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_queryset(self):
community_slug = self.kwargs.get('community_slug')
return CommunityPost.objects.filter(
community__slug=community_slug
).select_related('author', 'community').prefetch_related('tags', 'likes')
def perform_create(self, serializer):
community = get_object_or_404(Community, slug=self.kwargs.get('community_slug'))
serializer.save(author=self.request.user, community=community)
def get_serializer_class(self):
if self.request.method == 'POST':
return CommunityPostCreateSerializer
return CommunityPostListSerializer
class CommunityPostDetailView(generics.RetrieveUpdateDestroyAPIView):
"""Get, update or delete a specific post"""
serializer_class = CommunityPostDetailSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
lookup_field = 'slug'
def get_queryset(self):
community_slug = self.kwargs.get('community_slug')
return CommunityPost.objects.filter(
community__slug=community_slug
).select_related('author', 'community').prefetch_related('tags', 'likes', 'comments')
# ====================== Comment Views ======================
class CommentListCreateView(generics.ListCreateAPIView):
"""List comments or add a new comment on a post"""
serializer_class = CommentSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_queryset(self):
post_slug = self.kwargs.get('post_slug')
return Comment.objects.filter(
post__slug=post_slug, parent=None
).select_related('user').prefetch_related('replies')
def perform_create(self, serializer):
post = get_object_or_404(CommunityPost, slug=self.kwargs.get('post_slug'))
serializer.save(user=self.request.user, post=post)
# ====================== Membership Views ======================
class JoinCommunityView(generics.CreateAPIView):
"""Join a community"""
serializer_class = CommunityMembershipSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
community = get_object_or_404(Community, slug=self.kwargs.get('slug'))
serializer.save(user=self.request.user, community=community)
2. URLs (community/urls.py)
from django.urls import path
from .views import (
CommunityListCreateView,
CommunityDetailView,
CommunityPostListCreateView,
CommunityPostDetailView,
CommentListCreateView,
JoinCommunityView,
)
app_name = 'community'
urlpatterns = [
# Communities
path('communities/', CommunityListCreateView.as_view(), name='community-list-create'),
path('communities/<slug:slug>/', CommunityDetailView.as_view(), name='community-detail'),
# Join Community
path('communities/<slug:slug>/join/', JoinCommunityView.as_view(), name='join-community'),
# Posts
path('communities/<slug:community_slug>/posts/',
CommunityPostListCreateView.as_view(), name='post-list-create'),
path('communities/<slug:community_slug>/posts/<slug:slug>/',
CommunityPostDetailView.as_view(), name='post-detail'),
# Comments
path('communities/<slug:community_slug>/posts/<slug:post_slug>/comments/',
CommentListCreateView.as_view(), name='comment-list-create'),
]
3. SEO Meta Title, Description & Keywords
Updated save() Methods in Models
Community Model
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.name)[:150]
self.slug = f"{base_slug}-{uuid4().hex[:8]}"
# SEO Auto Generation
if not self.meta_title:
self.meta_title = f"{self.name} Community | Discussions & Resources"
if not self.meta_description:
if self.description:
self.meta_description = self.description[:157] + ("..." if len(self.description) > 160 else "")
else:
self.meta_description = f"Join {self.name} - A vibrant community to discuss, share knowledge and connect with like-minded people."
if not self.meta_keywords:
keywords = slugify(self.name).replace('-', ', ')
self.meta_keywords = f"{keywords}, community, forum, discussion, members"
super().save(*args, **kwargs)
CommunityPost Model
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)[:150]
self.slug = f"{base_slug}-{uuid4().hex[:6]}"
# SEO Auto Generation
if not self.meta_title:
self.meta_title = f"{self.title} | {self.community.name}"
if not self.meta_description:
if self.content:
desc = self.content[:157].strip()
self.meta_description = desc + ("..." if len(self.content) > 160 else "")
else:
self.meta_description = f"Read this interesting post in the {self.community.name} community."
super().save(*args, **kwargs)
Updated Serializers (Include Meta Fields)
# In CommunityDetailSerializer
fields = [
'id', 'name', 'slug', 'description', 'is_public',
'meta_title', 'meta_description', 'meta_keywords', # SEO Fields
'member_count', 'created_by', 'created_at'
]
# In CommunityPostDetailSerializer
fields = [
'id', 'title', 'slug', 'content',
'meta_title', 'meta_description', # SEO Fields
'community', 'author', 'tags',
'like_count', 'comment_count', 'is_liked', 'created_at'
]
Recommended Meta Lengths
| Field | Recommended Length | Purpose |
|---|---|---|
meta_title | 50–60 characters | Page title in search results |
meta_description | 150–160 characters | Description in search results |
meta_keywords | 5–10 comma-separated | Helps search engines |
Next Steps Suggestion:
Would you like me to add the following in MDX format as well?
- Custom Permissions (IsAdmin, IsModerator, IsMember)
- Like/Unlike functionality with
@action - ViewSets version
- Pagination + Filtering
Just reply with what you need next!