Python Django Social Media App From Scratch

Written by

in

Building a social media platform from scratch may sound like a daunting task, but with Python Django’s robust framework, you can turn a simple idea into a fully‑featured web app in a matter of weeks. In this step‑by‑step guide we’ll walk through everything you need—from project setup and data modeling to real‑time updates and SEO best practices—so you can launch a scalable, secure, and SEO‑friendly social media app that stands out in today’s crowded digital landscape.

Why Choose Django for a Social Media App?

  • Rapid Development: Django’s “batteries‑included” philosophy provides authentication, admin panels, and ORM out of the box.
  • Scalability: Built‑in support for caching, middleware, and asynchronous tasks makes it easy to grow with your user base.
  • Security: Automatic protection against XSS, CSRF, and SQL injection keeps user data safe.
  • Community & Packages: A massive ecosystem (e.g., django‑rest‑framework, django‑channels) speeds up feature implementation.
  • SEO‑Ready: Clean URLs, sitemap generation, and template tags help search engines index your content effectively.

Project Setup: From Zero to Django Project

Install Python and Create a Virtual Environment

# Install the latest Python 3.x
$ sudo apt-get install python3 python3-venv

# Create and activate a virtual environment
$ python3 -m venv env
$ source env/bin/activate

# Upgrade pip
(env) $ pip install --upgrade pip

Start a New Django Project

# Install Django and supporting packages
(env) $ pip install django djangorestframework django-allauth

# Create the project
(env) $ django-admin startproject socialapp
(env) $ cd socialapp

# Create the core app
(env) $ python manage.py startapp core

Don’t forget to add 'core', 'rest_framework', and 'allauth' to INSTALLED_APPS in settings.py, and configure the database (SQLite for development, PostgreSQL for production).

Designing the Core Models

User Profile Model

While Django’s built‑in User model handles authentication, a separate Profile model lets you store extra information such as avatar, bio, and follower count.

from django.contrib.auth.models import User
from django.db import models

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    avatar = models.ImageField(upload_to='avatars/', default='avatars/default.jpg')
    bio = models.TextField(max_length=500, blank=True)
    followers = models.ManyToManyField('self', symmetrical=False, related_name='following', blank=True)

    def __str__(self):
        return self.user.username

Post, Comment, and Like Models

These models form the backbone of any social feed.

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

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

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

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

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

Building the Key Features

User Registration and Authentication

Leverage django-allauth for a seamless sign‑up flow, social login, and email verification.

# settings.py
INSTALLED_APPS += [
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
]

SITE_ID = 1

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
)

ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_EMAIL_REQUIRED = True

Run migrations and configure URLs:

# urls.py
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
    path('', include('core.urls')),
]

Creating Posts and Feeds

Use Django’s generic class‑based views (CBVs) to handle CRUD operations efficiently.

from django.views.generic import ListView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin

class FeedView(LoginRequiredMixin, ListView):
    model = Post
    template_name = 'core/feed.html'
    paginate_by = 10

    def get_queryset(self):
        # Show posts from followed users + self
        following = self.request.user.profile.following.all()
        return Post.objects.filter(author__in=following).order_by('-created_at')

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    fields = ['content', 'image']
    template_name = 'core/post_create.html'

    def form_valid(self, form):
        form.instance.author = self.request.user.profile
        return super().form_valid(form)

Implementing Likes and Comments

AJAX calls keep the user experience fluid. Below is a simple Django view for toggling likes.

from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required

@require_POST
@login_required
def toggle_like(request, post_id):
    post = Post.objects.get(id=post_id)
    profile = request.user.profile
    liked, created = Like.objects.get_or_create(post=post, user=profile)
    if not created:
        liked.delete()
        status = 'unliked'
    else:
        status = 'liked'
    return JsonResponse({'status': status, 'likes_count': post.likes.count()})

Follow System

Following is a many‑to‑many relationship on the Profile model. Provide a view that adds or removes a follower.

@login_required
def follow_toggle(request, username):
    target = User.objects.get(username=username).profile
    profile = request.user.profile
    if target in profile.following.all():
        profile.following.remove(target)
        action = 'unfollowed'
    else:
        profile.following.add(target)
        action = 'followed'
    return JsonResponse({'action': action})

Adding Real‑Time Features with Django Channels

To deliver instant notifications (new likes, comments, or followers), integrate django‑channels and WebSockets.

  1. Install the package: pip install channels.
  2. Add 'channels' to INSTALLED_APPS and set ASGI_APPLICATION = 'socialapp.asgi.application'.
  3. Create a consumer that broadcasts events to a group named after the user’s ID.
# consumers.py
from channels.generic.websocket import AsyncJsonWebsocketConsumer

class NotificationConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        if self.scope['user'].is_anonymous:
            await self.close()
        else:
            self.group_name = f'user_{self.scope["user"].id}'
            await self.channel_layer.group_add(self.group_name, self.channel_name)
            await self.accept()

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

    async def send_notification(self, event):
        await self.send_json(event['content'])

Whenever a like or comment is saved, fire a channel layer event to push the notification instantly.

Testing and Debugging

  • Unit Tests: Use django.test.TestCase to verify model constraints, view permissions, and API responses.
  • Integration Tests: Leverage pytest‑django for end‑to‑end scenarios, especially real‑time features.
  • Debug Toolbar: Install

Comments

Leave a Reply

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