Skip to content

ulugbek101/django-starter-pack

Repository files navigation

Django Starter Pack

A production-ready Django project template. Clone it, copy .env.example to .env, and start building.

What's included

Feature Details
Split settings development, production, testing — switch by setting DJANGO_ENV
Custom User model Pre-wired so you can add fields anytime without migration headaches
SQLite in dev No database setup needed for local development
PostgreSQL in production Runs as a Docker container from the official Postgres image
Redis + Celery Task queue and broker running as Docker containers
Docker setup docker-compose.yml for dev, docker-compose.prod.yml for production
Nginx Reverse proxy in production; serves static and media files directly
Logging Console everywhere; file logging + admin error emails in production
WhiteNoise Compresses and serves static files in production without Nginx config per file
django-debug-toolbar Shows SQL queries, cache, and request info in the browser during development
Makefile Shortcuts for common commands so you don't type long commands repeatedly

Project structure

project/
├── apps/                        Your Django applications go here
│   └── users/                   Custom user model (always keep this)
├── config/                      Django project package
│   ├── settings/
│   │   ├── base.py              Settings shared by all environments
│   │   ├── development.py       Local dev: SQLite, console email, debug toolbar
│   │   ├── production.py        Production: PostgreSQL, SMTP, HTTPS headers
│   │   └── testing.py           Tests: in-memory SQLite, fast password hashing
│   ├── celery.py                Celery application setup
│   ├── tasks.py                 Project-wide Celery tasks (app tasks go in each app)
│   ├── urls.py                  Root URL config
│   ├── wsgi.py
│   └── asgi.py
├── docker/
│   └── nginx/
│       └── nginx.conf           Nginx config for production
├── requirements/
│   ├── base.txt                 Packages needed in all environments
│   ├── development.txt          Dev extras: debug toolbar, pytest, ipython
│   └── production.txt           Production extras: psycopg2
├── scripts/
│   └── entrypoint.sh            Production Docker entrypoint: waits for DB, migrates, collectstatic
├── static/                      Your static files (CSS, JS, images)
├── staticfiles/                 Auto-generated by collectstatic — do not edit manually
├── media/                       User-uploaded files
├── templates/                   HTML templates
│   ├── base.html
│   ├── 404.html
│   └── 500.html
├── logs/                        Log files written in production
├── docker-compose.yml           Dev stack: Django + Redis + Celery
├── docker-compose.prod.yml      Prod stack: adds PostgreSQL + Nginx
├── Dockerfile                   Multi-stage: development and production targets
├── Makefile                     Run `make help` to see all commands
├── setup.cfg                    pytest and flake8 config
├── conftest.py                  Sets DJANGO_ENV=testing before pytest loads settings
└── .env.example                 Copy to .env and fill in values

Quick start — local development without Docker

Uses SQLite. No database setup needed.

1. Clone the repo

git clone <your-repo-url>
cd django-starter-pack

2. Create and activate a virtual environment

python -m venv .venv

# Windows
.venv\Scripts\activate

# Mac / Linux
source .venv/bin/activate

3. Install dependencies

pip install -r requirements/development.txt

4. Set up environment variables

cp .env.example .env

Open .env and set SECRET_KEY. Generate one with:

python -c "import secrets; print(secrets.token_hex(50))"

5. Create and apply migrations

make setup

Or run manually:

python manage.py makemigrations
python manage.py migrate

6. Create an admin user

python manage.py createsuperuser

7. Start the server

python manage.py runserver

Open http://127.0.0.1:8000/admin/ — log in with the admin account you just created.


Quick start — Docker development

Uses Docker with Redis and Celery. Django still uses SQLite inside the container.

1. Copy and edit environment variables

cp .env.example .env

Set SECRET_KEY at minimum. Everything else has a default that works out of the box.

2. Start the stack

docker-compose up -d

This starts three containers: web (Django), redis, and celery (worker).

3. Run migrations

make docker-setup

4. Create an admin user

make docker-superuser

5. Open the app

http://localhost:8000/admin/

Creating a new app

python manage.py startapp myapp apps/myapp

Open apps/myapp/apps.py and change the name field:

class MyappConfig(AppConfig):
    name = 'apps.myapp'   # <-- add the apps. prefix

Register it in config/settings/base.py:

LOCAL_APPS = [
    'apps.users',
    'apps.myapp',   # add this
]

Adding fields to the User model

Open apps/users/models.py and add fields to the User class:

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

class User(AbstractUser):
    phone = models.CharField(max_length=20, blank=True)
    avatar = models.ImageField(upload_to='avatars/', blank=True)

Then create and apply the migration:

python manage.py makemigrations
python manage.py migrate

Writing Celery tasks

App-specific tasks — create tasks.py inside your app:

# apps/myapp/tasks.py
from celery import shared_task

@shared_task
def send_welcome_email(user_id):
    from apps.users.models import User
    user = User.objects.get(pk=user_id)
    # send email logic here

Project-wide tasks — add them to config/tasks.py.

Call a task from your code:

from apps.myapp.tasks import send_welcome_email

send_welcome_email.delay(user.id)  # runs in background via Celery

Start a local worker (if not using Docker):

make worker

How logging works

Development: Everything prints to the terminal. No files are written.

Production:

  • WARNING and above go to logs/app.log (rotates at 10 MB, keeps 5 old files)
  • Every unhandled 500 error sends a full HTML email to everyone in DJANGO_ADMINS
  • All output also goes to stdout so docker logs captures it

Using the logger in your code:

import logging

logger = logging.getLogger('apps.myapp')  # replace myapp with your app name

logger.info("Order created: %s", order.id)
logger.warning("Low stock for product %s", product.id)
logger.error("Payment failed for user %s", user.id)

How error emails work

When a request causes a 500 error in production, Django sends a full report to the people listed in DJANGO_ADMINS. The email has the full stack trace, request headers, POST data, and session contents.

Setup:

  1. Set DJANGO_ADMINS=Your Name:your@email.com in .env
  2. Fill in EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD
  3. Make sure DJANGO_ENV=production

In development, emails are printed to the terminal — so you can test email flows without an SMTP server.


Environment variables reference

All variables are in .env.example. Key ones:

Variable Required Description
SECRET_KEY Always Django's signing key. Keep it secret.
DJANGO_ENV Always development, production, or testing
ALLOWED_HOSTS Production Comma-separated list of accepted hostnames
DB_NAME, DB_USER, DB_PASSWORD Production PostgreSQL credentials
DB_HOST Production Hostname of the database; use db in Docker
REDIS_URL When using Celery Redis connection URL
EMAIL_HOST, EMAIL_HOST_USER, etc. Production SMTP server for sending emails
DJANGO_ADMINS Production Who gets 500 error emails: Name:email@example.com
SECURE_SSL_REDIRECT Production Set False if your proxy already handles HTTPS

Running tests

# Run all tests
pytest

# Run with a coverage report
pytest --cov=apps --cov-report=term-missing

# Run tests in a specific app
pytest apps/users/

Tests run with DJANGO_ENV=testing automatically (set in conftest.py), which means:

  • SQLite in memory (fast, no cleanup needed)
  • Emails go to django.core.mail.outbox instead of being sent
  • MD5 password hashing (faster than bcrypt)
  • All logging silenced

Deployment

1. Prepare environment variables

cp .env.example .env

Edit .env with production values:

  • DJANGO_ENV=production
  • ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
  • PostgreSQL and email credentials
  • DJANGO_ADMINS for error notifications

2. Start the production stack

docker-compose -f docker-compose.prod.yml up -d

This starts PostgreSQL, Redis, Django (Gunicorn), Celery worker, and Nginx.

The entrypoint script in the web container automatically:

  • Waits for PostgreSQL to be ready
  • Runs migrate
  • Runs collectstatic

3. Create the first admin user

docker-compose -f docker-compose.prod.yml exec web python manage.py createsuperuser

4. Access the app

Nginx listens on port 80. Point your domain's DNS to the server's IP address.


Makefile commands

Run make help to list all commands.

make run              Start the development server
make shell            Open Django interactive shell
make setup            Create migrations and apply them (first-time setup)
make migrate          Apply existing migrations
make makemigrations   Create new migration files
make superuser        Create an admin user
make test             Run all tests
make lint             Check code style with flake8
make worker           Start Celery worker locally
make beat             Start Celery beat scheduler locally

make docker-up        Start dev Docker stack
make docker-down      Stop dev Docker stack
make docker-migrate   Run migrations in Docker
make docker-superuser Create admin user in Docker

make prod-up          Start production Docker stack
make prod-down        Stop production Docker stack
make prod-logs        Stream production container logs

About

Django project with some initial configurations

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Contributors