Python Django Social Media App From Scratch

Written by

in

Building a social media app with Python Django from scratch might sound daunting, but with a clear roadmap and the right tools, you can launch a fully functional platform that rivals the big players. In this step‑by‑step guide we’ll cover everything you need—from setting up your development environment to deploying a production‑ready application. Whether you’re a seasoned Django developer or a curious beginner, you’ll walk away with a solid foundation, reusable code snippets, and SEO‑friendly practices that help your app rank higher in search results.

Why Choose Django for a Social Media App?

Django’s “batteries‑included” philosophy makes it an ideal choice for complex, data‑driven projects. Here are a few reasons why developers love Django for social networking sites:

  • Rapid development: Built‑in admin, ORM, and authentication reduce boilerplate.
  • Scalability: Handles high traffic with proper caching and async support.
  • Security: Protection against XSS, CSRF, and SQL injection out of the box.
  • Community & Packages: Rich ecosystem (e.g., django‑rest‑framework, django‑channels) accelerates feature implementation.

1. Setting Up the Development Environment

Prerequisites

  1. Python 3.10 or later
  2. Virtualenv or pipenv
  3. Git for version control
  4. Node.js (optional, for front‑end tooling)

Installation Steps

# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate   # On Windows use `venv\Scripts\activate`

# Install Django and supporting packages
pip install django djangorestframework django-channels psycopg2-binary

# Start a new project
django-admin startproject socialapp
cd socialapp

# Create the core app
python manage.py startapp core

2. Designing the Project Structure

A clean layout makes maintenance easier. Below is a recommended file hierarchy:

socialapp/
│
├─ core/                 # Main app (models, views, serializers)
│   ├─ migrations/
│   ├─ templates/
│   │   └─ core/
│   ├─ static/
│   │   └─ core/
│   ├─ admin.py
│   ├─ models.py
│   ├─ views.py
│   ├─ urls.py
│   └─ consumers.py      # For WebSocket handling
│
├─ socialapp/            # Project settings
│   ├─ settings.py
│   ├─ urls.py
│   └─ asgi.py
│
├─ requirements.txt
└─ manage.py

3. Implementing User Authentication

Django’s built‑in User model covers most needs, but extending it gives you flexibility for profile pictures, bio, and follower relationships.

Custom User Model

# core/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    bio = models.CharField(max_length=255, blank=True)
    avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)

    def __str__(self):
        return self.username

Remember to update settings.py:

# socialapp/settings.py
AUTH_USER_MODEL = 'core.CustomUser'

Registration & Login Views

# core/views.py
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
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})

4. Core Models: Posts, Comments, Likes, and Followers

Post Model

# core/models.py (continued)
class Post(models.Model):
    author = models.ForeignKey('core.CustomUser', on_delete=models.CASCADE, related_name='posts')
    content = models.TextField()
    image = models.ImageField(upload_to='posts/', blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.author.username}: {self.content[:30]}'

Comment and Like Models

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey('core.CustomUser', on_delete=models.CASCADE)
    body = models.CharField(max_length=300)
    created_at = models.DateTimeField(auto_now_add=True)

class Like(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='likes')
    user = models.ForeignKey('core.CustomUser', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('post', 'user')

Followers (Self‑Referencing Many‑To‑Many)

class Follow(models.Model):
    follower = models.ForeignKey('core.CustomUser', related_name='following', on_delete=models.CASCADE)
    following = models.ForeignKey('core.CustomUser', related_name='followers', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('follower', 'following')

5. Building Views, Serializers, and URLs

RESTful API with Django REST Framework

# core/serializers.py
from rest_framework import serializers
from .models import Post, Comment, Like

class PostSerializer(serializers.ModelSerializer):
    author = serializers.StringRelatedField(read_only=True)
    likes_count = serializers.IntegerField(source='likes.count', read_only=True)
    comments_count = serializers.IntegerField(source='comments.count', read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'author', 'content', 'image', 'created_at', 'likes_count', 'comments_count']

API ViewSet

# core/views.py (API part)
from rest_framework import viewsets, permissions
from .models import Post
from .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.select_related('author').prefetch_related('likes', 'comments')
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

URL Configuration

# core/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register(r'posts', views.PostViewSet, basename='post')

urlpatterns = [
    path('api/', include(router.urls)),
    path('signup/', views.signup_view, name='signup'),
    # Additional routes for login, logout, profile, etc.
]

6. Crafting Responsive Templates with Bootstrap

Using a modern CSS framework speeds up UI development and improves SEO through clean markup.

<!-- core/templates/core/feed.html -->
{% extends "base.html" %}
{% block content %}
<h2 class="mb-3">Your Feed</h2> {% for post in posts %} <div class="card mb-3"> <div class="card-body"> <h5 class="card-title">{{ post.author.username }}</h5> <p class="card-text">{{ post.content|linebreaks }}</p> {% if post.image %} <img src="{{ post.image.url }}" class="img-fluid" alt="Post image"> {% endif %} <small class="text-muted">{{ post.created_at|naturaltime }}</small> </div> </div> {% empty %} <p>No posts yet. Follow someone or create a new post!</p> {% endfor %}
{% endblock %}

7. Adding Real‑Time Features with Django Channels

Live notifications and chat are essential for a modern social experience.

Install and Configure Channels

# Install
pip install channels

# socialapp/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels

Comments

Leave a Reply

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