HOME BLOGS ABOUT CONTACT

Building a Scalable Django Project Structure (Step by Step Guide)

tania andrew Suresh Thapa
| 24 Sep, 2025 | 587 views
0
0
Building a Scalable Django Project Structure (Step by Step Guide)

Building a Scalable Django Project Structure (Step by Step Guide)

When you start a Django project, it’s tempting to keep everything inside a single settings.py file and clutter your root folder with configurations. This works for toy projects, but it quickly becomes painful when you scale to production.

 

A scalable Django structure looks like this:

ZeroTrustSpace/
├── config/
│   ├── __init__.py
│   ├── urls.py
│   ├── wsgi.py
│   └── settings/
│       ├── __init__.py
│       ├── base.py
│       ├── local.py
│       └── production.py
├── manage.py

 

Why this structure?

  • Separation of concerns → Base settings for all environments, with overrides for local development and production.
  • Clarity → All config lives in a single config/ directory.
  • Scalability → Easy to extend with more apps and environments.
  • Maintainability → No spaghetti settings.py.

 

Step 1: Create the project

django-admin startproject config .

Then rename the outer project folder to your project name (ZeroTrustSpace/) and keep config/ as the inner config directory.

 

Step 2: Split your settings

Inside config/settings/:

base.py

Contains settings shared across all environments.

from pathlib import Path
import os

BASE_DIR = Path(__file__).resolve().parent.parent.parent

SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "insecure-secret")
DEBUG = False

ALLOWED_HOSTS = ["*"]

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # your apps here
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "config.urls"
WSGI_APPLICATION = "config.wsgi.application"

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

STATIC_URL = "/static/"
MEDIA_URL = "/media/"

 

local.py

For development only.

from .base import *

DEBUG = True
ALLOWED_HOSTS = ["*"]

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

 

production.py

For production deployment.

from .base import *

DEBUG = False
ALLOWED_HOSTS = ["zerotrustspace.com"]

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.getenv("POSTGRES_DB"),
        "USER": os.getenv("POSTGRES_USER"),
        "PASSWORD": os.getenv("POSTGRES_PASSWORD"),
        "HOST": os.getenv("POSTGRES_HOST", "localhost"),
        "PORT": os.getenv("POSTGRES_PORT", "5432"),
    }
}

SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True

 

Step 3: Configure WSGI and manage.py

Both files must know which settings to load.

config/wsgi.py

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")

application = get_wsgi_application()

 

manage.py

#!/usr/bin/env python
import os
import sys

def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

if __name__ == "__main__":
    main()

 

Step 4: Add .env support (optional but recommended)

Install django-environ:

pip install django-environ

 

Update base.py:

import environ

env = environ.Env()
environ.Env.read_env(os.path.join(BASE_DIR, ".env"))

SECRET_KEY = env("DJANGO_SECRET_KEY", default="unsafe-secret")

 

Create .env:

DJANGO_SECRET_KEY=super-secret-key
POSTGRES_DB=zerotrustspace
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password123

 

Step 5: Add new apps in apps/

Instead of dumping apps in the root, create an apps/ folder:

ZeroTrustSpace/
├── apps/
│   ├── blog/
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── views.py
│   │   └── urls.py

 

Update INSTALLED_APPS in base.py:

INSTALLED_APPS += ["apps.blog"]

 

Benefits

  • Easy to maintain
  • Clean separation between environments
  • Production-ready with PostgreSQL + environment variables
  • Extensible for Docker, CI/CD, multi-app projects

 

With this setup, you’re already ahead of 90% of beginner Django devs.

 

Tags:

django python

Comments

Please login to leave a comment.

No comments yet. Be the first to comment!