Python Django Social Media App From Scratch

Written by

in

Imagine building a full‑featured social media platform that lets users share posts, follow friends, and chat in real time—all powered by the clean, scalable Python framework Django. In this step‑by‑step guide we’ll walk you through creating a Python Django social media app from scratch, covering everything from project setup and data modeling to real‑time notifications and deployment. Whether you’re a seasoned Django developer or just getting started, you’ll walk away with a production‑ready codebase and a solid understanding of the best practices that make Django the go‑to choice for modern web applications.

Why Choose Django for a Social Media App?

Django’s “batteries‑included” philosophy means you get a robust ORM, an authentication system, and a powerful admin interface out of the box—exactly the building blocks you need for a social network. Here are the top reasons developers pick Django for social media projects:

  • Rapid development: Built‑in admin and authentication cut weeks of work.
  • Scalability: Django scales from a single‑server prototype to a multi‑node production cluster.
  • Security: Automatic protection against XSS, CSRF, and SQL injection.
  • Community & Packages: Rich ecosystem (e.g., django‑rest‑framework, django‑channels) accelerates feature development.

Project Setup: From Scratch to Running Server

1. Install Python and Django

# Ensure you have Python 3.11+ installed
python -V

# Create a virtual environment
python -m venv env
source env/bin/activate   # On Windows: env\Scripts\activate

# Install Django and supporting packages
pip install django djangorestframework django‑channels

2. Create the Project and Core Apps

# Start a new Django project called "socialnetwork"
django-admin startproject socialnetwork
cd socialnetwork

# Create reusable apps
python manage.py startapp accounts   # User auth & profiles
python manage.py startapp posts      # Posts, likes, comments
python manage.py startapp chat       # Real‑time messaging

3. Configure Settings

Open socialnetwork/settings.py and add the new apps to INSTALLED_APPS. Also enable channels and set the ASGI application:

INSTALLED_APPS = [
    # Django defaults...
    'django.contrib.admin',
    'django.contrib.auth',
    # Third‑party
    'rest_framework',
    'channels',
    # Your apps
    'accounts',
    'posts',
    'chat',
]

# Channels configuration
ASGI_APPLICATION = 'socialnetwork.asgi.application'
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels.layers.InMemoryChannelLayer"
    },
}

Designing the Data Model

A well‑structured data model is the backbone of any social platform. Below is a simplified schema that you can expand as needed.

  • UserProfile – Extends Django’s User with avatar, bio, and follower relationships.
  • Post – Stores text, optional image, timestamp, and a foreign key to the author.
  • Like – Many‑to‑one relation linking a UserProfile to a Post.
  • Comment – Text, author, post reference, and creation date.
  • Message – Real‑time chat model with sender, receiver, content, and read status.

Example of the Post model in posts/models.py:

from django.db import models
from django.conf import settings

class Post(models.Model):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='posts'
    )
    content = models.TextField(max_length=500)
    image = models.ImageField(upload_to='post_images/', blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

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

Building Core Features

User Authentication and Profiles

Django’s built‑in auth app handles sign‑up, login, and password reset. To add profile data, create a UserProfile model linked via a OneToOneField and use Django signals to auto‑create a profile on user registration.

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    avatar = models.ImageField(upload_to='avatars/', default='avatars/default.jpg')
    bio = models.CharField(max_length=200, blank=True)

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

Expose these endpoints with Django REST Framework (DRF) for a modern JavaScript front‑end:

from rest_framework import serializers, viewsets, permissions
from .models import UserProfile

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('id', 'user', 'avatar', 'bio')

class UserProfileViewSet(viewsets.ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticated]

Posting, Liking, and Commenting

Implement CRUD APIs for posts using DRF viewsets. Likes can be toggled with a simple POST request that creates or deletes a Like instance.

# posts/views.py
from rest_framework import viewsets, permissions
from .models import Post, Like, Comment
from .serializers import PostSerializer, LikeSerializer, CommentSerializer

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

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

class LikeToggleView(viewsets.GenericViewSet):
    permission_classes = [permissions.IsAuthenticated]

    def create(self, request, pk=None):
        post = Post.objects.get(pk=pk)
        like, created = Like.objects.get_or_create(user=request.user, post=post)
        if not created:
            like.delete()
            return Response({'status': 'unliked'})
        return Response({'status': 'liked'})

Real‑Time Updates with Django Channels

Social platforms thrive on instant feedback. django‑channels adds WebSocket support to Django, enabling live notifications, chat, and feed updates without page reloads.

# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group = f'chat_{self.room_name}'
        await self.channel_layer.group_add(self.room_group, self.channel_name)
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.room_group, self.channel_name)

    async def receive(self, text_data):
        data = json.loads(text_data)
        await self.channel_layer.group_send(
            self.room_group,
            {
                'type': 'chat_message',
                'message': data['message'],
                'user': self.scope['user'].username,
            }
        )

    async def chat_message(self, event):
        await self.send(text_data=json.dumps({
            'message': event['message'],
            'user': event['user'],
        }))

Don’t forget to route the WebSocket URL in socialnetwork/routing.py and include it in asgi.py.

Deploying Your Django Social Media App

Once development is complete, move to production with these essential steps:

  • Choose a host: DigitalOcean, AWS EC2, or Heroku (with Docker for Channels).
  • Configure a production‑ready web server: Use gunicorn + nginx for HTTP and daphne for ASGI.
  • Set environment variables: DEBUG=False

Comments

Leave a Reply

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