Building an Instagram Clone Using Django
Introduction
Instagram is one of the most popular social media platforms, allowing users to share photos, videos, and stories. In this blog, we’ll build a simplified version of Instagram using Django. The project will include features like:
- User Authentication: Register, login, and logout.
- Post Creation: Upload images with captions and hashtags.
- Dark Mode Toggle: Switch between light and dark themes.
- Profile Editing: Update Profile picture, Bio and website
- Comments and Likes: Interact with posts.
- Followers and Following: Build a social network.
- Reels: Upload and view short videos.
- Messaging: Chat with other users.
- Stories: Share temporary photos and videos.
This blog will guide you through the implementation of each feature step by step. By the end, you’ll have a fully functional Instagram clone!
Technologies Used
- Backend: Django (Python)
- Frontend: HTML, CSS, JavaScript, Bootstrap
- Database: SQLite (for development)
Other Libraries: Pillow (for image handling), Django Signals (for automatic profile creation)
File Structure
Here’s an overview of the project structure:

Setup Instructions
Before we start coding, let’s set up the project environment.
1.Create a Virtual Environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
2.Install Django:
pip install django
3.Create the Django Project:
django-admin startproject insta_clone
cd insta_clone
4.Create the Apps:
python manage.py startapp accounts
python manage.py startapp posts
5.Install Pillow (for image handling):
pip install pillow
6.Add Apps to INSTALLED_APPS:
- Open insta_clone/settings.py and add accounts and posts to INSTALLED_APPS:
INSTALLED_APPS = [
...
'accounts',
'posts',
]
7.Run Migrations:
python manage.py migrate
Static Files and Images
The project uses static files (CSS, JavaScript, and images) to style the frontend. Here’s how to set it up:
- Create a Static Folder:
- Inside the root project directory (insta_clone), create a folder named static.
- Inside the static folder, create another folder named images.
- Add Static Files:
- Place your CSS and JavaScript files in the static folder.
- Download appropriate images (e.g., Instagram logos, icons, etc.) from the internet and place them in the static/images folder.
- Configure Static Files in settings.py:
Add the following lines to settings.py to serve static files during development:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
4. Using Static Files in Templates:
Load static files in your templates using the {% load static %} tag. For example:

Note: You can download images like the Instagram logo, app store badges, and other icons from the internet and place them in the static/images folder. Just as I did for my project
Feature 1: User Authentication
1.Custom User Model
To use email-based authentication, we’ll create a custom user model in accounts/models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email' # Use email for login
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.email
Update settings.py to use the custom user model:
AUTH_USER_MODEL = 'accounts.CustomUser'
Run migrations to apply the changes:
python manage.py makemigrations
python manage.py migrate
2.User Registration
Create a registration form in accounts/forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class RegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = CustomUser
fields = ['username', 'email', 'password1', 'password2']
Add the registration view in accounts/views.py:
from django.shortcuts import render, redirect
from .forms import RegisterForm
def register(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = RegisterForm()
return render(request, 'accounts/register.html', {'form': form})
3.User Login:
Create a login form in accounts/forms.py:
from django import forms
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
username = forms.EmailField(label="Email") # Use email for login
Add the login view in accounts/views.py:
python
Copy
from django.contrib.auth import login, authenticate
from .forms import LoginForm
def login_view(request):
if request.method == "POST":
email = request.POST.get("email")
password = request.POST.get("password")
user = authenticate(request, email=email, password=password)
if user:
login(request, user)
return redirect("home")
else:
return render(request, "accounts/login.html", {"error": "Invalid email or password."})
return render(request, "accounts/login.html")
4. User Logout
Add the logout view in accounts/views.py:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect('index')
5.Templates
- register.html: Registration form template.
- login.html: Login form template.
- index.html: Homepage with login and registration links.
Templates/accounts/register.html:
{% load static %}
<!DOCTYPE html>
<html lang=”en”>
<head>
<title>Instagram – Sign Up</title>
<link rel=”stylesheet” href=”https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css”>
<script src=”https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js”></script>
<style>
body {
background-color: #fafafa;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-direction: column;
}
.register-container {
background: white;
padding: 30px;
border-radius: 10px;
border: 1px solid #ddd;
width: 350px;
text-align: center;
}
.register-container img {
width: 200px;
margin-bottom: 10px;
}
.text-muted {
font-size: 14px;
margin-bottom: 10px;
}
.form-group {
margin-bottom: 12px;
}
.form-control {
font-size: 14px;
padding: 10px;
border-radius: 5px;
}
.btn-primary {
width: 100%;
font-size: 14px;
font-weight: bold;
padding: 8px;
margin-top: 10px;
}
.login-link {
margin-top: 15px;
font-size: 14px;
}
.separator {
display: flex;
align-items: center;
text-align: center;
margin: 15px 0;
}
.separator::before,
.separator::after {
content: “”;
flex: 1;
border-bottom: 1px solid #ddd;
}
.separator span {
padding: 0 10px;
font-size: 12px;
color: #aaa;
}
.signup-footer {
margin-top: 20px;
font-size: 14px;
text-align: center;
}
</style>
</head>
Get the app.