Initial setup to keep your Django project clean and scalable

I’m a dev using Django for some projects. When I first started, I just used django-admin startproject and begin coding right away. But later I realize, if we don’t setup project structure from the beginning, it will be very messy later, especially when your app gets bigger.

So in this post, I want to share some setups that help keep Django project clean, easy to maintain and scalable in the future. Let’s go!


1. Split settings.py into multiple files

By default, Django only give you one settings.py. But for real project, it's better to split it into:

/project_root/
  └── config/
      ├── settings/
      │   ├── base.py
      │   ├── dev.py
      │   └── prod.py
      └── __init__.py

Why?

  • base.py: common settings
  • dev.py: for local/dev environment
  • prod.py: for production (turn off debug, use real DB, etc.)

In manage.py and wsgi.py, you just change:

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

Later when deploy, you can switch to prod.


2. Use environment variables (.env) for secrets

Never hardcode your DB password, secret key, or API key in code. Use .env file instead.

Install django-environ or python-decouple (both are okay).

Example:

# .env
DEBUG=True
SECRET_KEY=super-secret-key
DATABASE_URL=postgres://user:pass@localhost:5432/mydb

Then in your base.py:

import environ
env = environ.Env()
environ.Env.read_env()

DEBUG = env.bool("DEBUG", default=False)
SECRET_KEY = env("SECRET_KEY")
DATABASES = {"default": env.db()}

✅ This is more secure and easy to manage between dev and prod.


3. Use custom User model from the beginning

Even if you don't need custom user right now, it’s good to set it up early. Otherwise, changing it later will be painful.

Create accounts app and make model like:

# accounts/models.py
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

In settings:

AUTH_USER_MODEL = 'accounts.User'

Done! You can still use default fields, and extend later if needed (like phone number, avatar, etc.)


4. Set up logging early

Don’t wait until errors happen in production. Setup logging from day 1:

LOGGING = {
  "version": 1,
  "handlers": {
    "console": {
      "class": "logging.StreamHandler"
    }
  },
  "root": {
    "handlers": ["console"],
    "level": "INFO"
  }
}

Later you can add file log or send to services like Sentry.


5. Install some useful dev tools

Some packages I always install for dev:

pip install django-debug-toolbar
pip install django-extensions
  • debug-toolbar: show SQL queries, request time, template used, etc.
  • django-extensions: has useful commands like show_urls, shell_plus, etc.

Also, add CORS and whitenoise early if plan to work with frontend or deploy static files:

pip install django-cors-headers whitenoise

6. Organize your apps by feature (optional)

Some people keep all logic in 1 app, like main, but I prefer split by feature:

project/
├── accounts/
├── blog/
├── payments/
├── common/

Each app has its own models, views, urls. It makes things cleaner and easier to maintain when team grows.


Final thoughts

These are small things, but they help a lot when project goes from MVP to production. I didn’t do these setups in my first Django project, and I regret later.

Hope this post can save your future self some headache.

Thanks for reading!