Python Django Social Media App From Scratch

Written by

in

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:

  1. User registration, login, and profile management.
  2. Creating, editing, and deleting text‑based posts.
  3. Like and comment functionality.
  4. Follow system (users can follow each other).
  5. Real‑time notifications using Django Channels.
  6. 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

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *