Building a Python Django social media app from scratch might sound like a daunting task, but with the right roadmap you can create a feature‑rich platform that rivals the big names—without reinventing the wheel. In this guide we’ll walk through every essential step: setting up the development environment, designing the data model, implementing user authentication, creating posts, likes, comments, and real‑time notifications, and finally deploying your app to production. Whether you’re a seasoned Django developer or just starting out, this tutorial gives you a clear, SEO‑friendly blueprint to launch a modern social network quickly and securely.
Why Choose Django for a Social Media App?
- Rapid development: Django’s “batteries‑included” philosophy provides an admin panel, ORM, and authentication out of the box.
- Scalability: With its robust middleware and support for async views, Django can handle millions of users when paired with the right infrastructure.
- Security: Built‑in protection against XSS, CSRF, SQL injection, and clickjacking keeps user data safe.
- Community & ecosystem: Thousands of reusable packages (e.g.,
django‑rest‑framework,channels) accelerate feature development.
Project Overview
Our social media app will include the following core features:
- User registration, login, and profile management.
- Creating, editing, and deleting text‑based posts.
- Like and comment functionality.
- Follow system (users can follow each other).
- Real‑time notifications using Django Channels.
- Responsive UI powered by Django templates and Tailwind CSS.
Step 1 – Setting Up the Development Environment
1.1 Install Python and Virtualenv
# Verify Python version (>=3.10 recommended)
python3 --version
# Create a virtual environment
python3 -m venv env
source env/bin/activate # On Windows use `env\Scripts\activate`
1.2 Install Django and Supporting Packages
pip install django djangorestframework django-filter
pip install channels channels-redis pillow # for real‑time and image handling
pip install psycopg2-binary # PostgreSQL driver
pip install django-taggit # optional tagging feature
1.3 Start a New Django Project
django-admin startproject socialsite
cd socialsite
django-admin startapp core
Step 2 – Designing the Data Model
At the heart of any social network lies a well‑structured database schema. Below is a simplified model that covers users, posts, likes, comments, and follows.
# core/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
bio = models.TextField(blank=True, max_length=500)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='posts/', null=True, blank=True)
def __str__(self):
return f'{self.author.username}: {self.content[:30]}'
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
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')
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Follow(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following')
following = models.ForeignKey(User, on_delete=models.CASCADE, related_name='followers')
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('follower', 'following')
2.1 Register Models in Admin
# core/admin.py
from django.contrib import admin
from .models import User, Post, Like, Comment, Follow
admin.site.register(User)
admin.site.register(Post)
admin.site.register(Like)
admin.site.register(Comment)
admin.site.register(Follow)
Step 3 – User Authentication & Profile Management
Django’s built‑in auth system handles most of the heavy lifting. We’ll extend the default User model to add a bio and avatar.
3.1 Update Settings
# socialsite/settings.py
AUTH_USER_MODEL = 'core.User'
INSTALLED_APPS = [
# default apps...
'core',
'rest_framework',
'channels',
# third‑party apps...
]
# Channels configuration
ASGI_APPLICATION = 'socialsite.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {'hosts': [('127.0.0.1', 6379)]},
},
}
3.2 Create Registration & Login Views
# core/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from .forms import SignUpForm
def signup_view(request):
if request.method == 'POST':
form = SignUpForm(request.POST, request.FILES)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('feed')
else:
form = SignUpForm()
return render(request, 'core/signup.html', {'form': form})
3.3 Build the Sign‑Up Form
# core/forms.py
from django import forms
from .models import User
class SignUpForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'email', 'bio', 'avatar', 'password')
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password'])
if commit:
user.save()
return user
Step 4 – CRUD Operations for Posts
We’ll use Django’s generic class‑based views (CBVs) to keep the code concise.
4.1 Post Creation View
# core/views.py (continued)
from django.views.generic import CreateView, ListView, DetailView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import Post
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['content', 'image']
template_name = 'core/post_form.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
4.2 Feed (List) View
class FeedView(LoginRequiredMixin, ListView):
model = Post
template_name = 'core/feed.html'
context_object_name = 'posts'
paginate_by = 10
def get_queryset(self):
# Show posts from users you follow + your own
following_ids = self.request.user.following.values_list('following_id', flat=True)
return Post.objects.filter(author__id__in=list(following_ids) + [self.request.user.id])\
.order_by('-created_at')
4.3 URL Configuration
# core/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.signup_view, name='signup'),
path('login/', views.LoginView.as_view(), name='login'), # use Django's built‑in
path('logout/', views.LogoutView.as_view(), name='logout'),
path('', views.FeedView.as_view(), name='feed'),
path('post/new/', views.PostCreateView.as_view(), name='post-create'),
# Additional CRUD URLs...
]
Step 5 – Adding Likes, Comments, and Follows
These interactions are best handled via AJAX calls to a small REST API powered by Django REST Framework (DRF).
5.1 Install & Configure DRF
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated'],
}
5.2 Serializers
# core/serializers.py
from rest_framework import serializers
from .models import Like, Comment, Follow
class LikeSerializer(serializers.ModelSerializer):
class Meta:
model = Like
fields = ('id', 'user', 'post', 'created_at')
read_only_fields = ('user',)
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'user', 'post', 'body', 'created_at')
read_only_fields = ('user',)
class FollowSerializer(serializers.ModelSerializer):
class Meta:
model = Follow
fields = ('id', 'follower', 'following', 'created_at')
read_only_fields = ('follower',)
5.3 API Views
# core/api_views.py
from rest_framework import viewsets, permissions
from .models import Like, Comment, Follow
from .serializers import LikeSerializer, CommentSerializer, FollowSerializer
class LikeViewSet(viewsets.ModelViewSet):
queryset = Like.objects.all()
serializer_class = LikeSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class CommentViewSet(viewsets.ModelViewSet
Leave a Reply