dj-settings
Organize Django settings.py into clearly sectioned blocks with banner-style headers. Use proactively whenever modifying src/project/settings.py — adding new settings, removing settings, or restructuring sections.
Works with
---
name: dj-settings
description: Organize Django settings.py into clearly sectioned blocks with banner-style headers. Use proactively whenever modifying src/project/settings.py — adding new settings, removing settings, or restructuring sections.
license: MIT
---
# Organize Django Settings
When modifying `src/project/settings.py`, enforce this structure.
## Single File, Not Split
Settings MUST live in a single `src/project/settings.py`. Do NOT split into `base.py` / `dev.py` / `prod.py` / `test.py`. Environment-specific values are read from environment variables via `python-decouple`; the code branches inline on a single environment variable where needed.
The split-settings pattern scatters the same logical concern across multiple files, forces a choice of `DJANGO_SETTINGS_MODULE` per environment, and makes diffs against "what does prod actually use?" hard to read. A single file with explicit `if ENV == "production":` branches is noisier but honest — everything is visible in one place.
```python
from decouple import config
ENV = config("ENV", default="local") # local | staging | production
DEBUG = ENV == "local"
if ENV == "production":
ALLOWED_HOSTS = ["app.example.com"]
SECURE_SSL_REDIRECT = True
else:
ALLOWED_HOSTS = ["*"]
```
The exact name of the environment variable is a project choice (`ENV`, `APP_ENV`, or a platform-specific variable like `RAILWAY_ENVIRONMENT_NAME`). The *pattern* — one variable, read once at the top of `settings.py`, branched inline — is fixed.
## Database via `dj-database-url`
`DATABASES["default"]` MUST be parsed from a single `DATABASE_URL` environment variable via `dj-database-url`:
```python
import dj_database_url
from decouple import config
DATABASES = {
"default": dj_database_url.parse(
config("DATABASE_URL", default="postgres://localhost/dev"),
conn_max_age=600,
),
}
```
Do NOT split the database connection into separate `NAME`/`USER`/`PASSWORD`/`HOST`/`PORT` environment variables. A single URL is simpler, matches every hosting platform's convention (Railway, Heroku, Fly, Render, Neon, Supabase), and is what Django tooling expects.
## Section Format
Every logical group of settings gets a banner header:
```python
# =============================================================================
# SECTION NAME
# =============================================================================
```
- Banner lines are exactly 77 characters (`# ` + 75 `=` characters)
- Section name is UPPERCASE
- One blank line before each banner (except at top of file)
- No blank lines between the banner and the first setting in that section
- No inline comments explaining what standard Django settings do — the section header is enough
## Section Order
Settings must appear in this order. Omit sections that have no settings.
1. **Imports and `BASE_DIR`** (no banner — these are preamble)
2. **LOGGING**
3. **SECURITY** — `SECRET_KEY`, `DEBUG`, `ALLOWED_HOSTS`, CORS, CSRF, cookie settings
4. **APPLICATION DEFINITION** — `INSTALLED_APPS`, `MIDDLEWARE`
5. **URLS AND APPLICATION** — `ROOT_URLCONF`, `ASGI_APPLICATION`, `WSGI_APPLICATION`. ASGI is the default runtime (see `dj-scaffold` Step 9), so `ASGI_APPLICATION = "project.asgi.application"` must be set. `WSGI_APPLICATION` stays in place for tooling that expects it.
6. **TEMPLATES**
7. **AUTH** — `AUTH_USER_MODEL`, `AUTH_PASSWORD_VALIDATORS`, `LOGIN_URL`
8. **DATABASE**
9. **SESSIONS**
10. **CACHING**
11. **INTERNATIONALIZATION** — `LANGUAGE_CODE`, `TIME_ZONE`, `USE_I18N`, `USE_TZ`
12. **STATIC FILES** — `STATIC_URL`, `STATIC_ROOT`, `STORAGES`, `DEFAULT_AUTO_FIELD`
13. **CELERY** — all `CELERY_*` settings
14. Any additional project-specific sections in alphabetical order
## `INSTALLED_APPS` Sub-grouping
Within `INSTALLED_APPS`, group entries with inline comments:
```python
INSTALLED_APPS = [
# Django core
"django.contrib.admin",
...
# Third-party
"corsheaders",
...
# Project apps
"products.apps.ProductsConfig",
"orders.apps.OrdersConfig",
]
```
Project apps must use the dotted path to their `AppConfig` subclass (e.g., `"myapp.apps.MyAppConfig"`), not the short app name.
## `MIDDLEWARE` Position Contract
`whitenoise.middleware.WhiteNoiseMiddleware` MUST appear **immediately after** `django.middleware.security.SecurityMiddleware` and **before** `django.contrib.sessions.middleware.SessionMiddleware`:
```python
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"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",
]
```
This position is non-negotiable: whitenoise must run after security headers are applied but before anything that could short-circuit the response or open a session. A misplaced `WhiteNoiseMiddleware` fails silently — the static-file shortcut is skipped and every request falls through to Django's view layer, so the symptom is "everything is slower" rather than a loud error. The position is enforced by a contract test (`example_project/tests/test_settings_middleware.py`).
In the STATIC FILES section, pair this with:
```python
STORAGES = {
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
"staticfiles": {"BACKEND": "whitenoise.storage.CompressedStaticFilesStorage"},
}
if DEBUG:
WHITENOISE_USE_FINDERS = True
WHITENOISE_AUTOREFRESH = True
```
`CompressedStaticFilesStorage` gives gzip + brotli precompression without filename hashing or a `staticfiles.json` manifest. `STATIC_ROOT` MUST be set (e.g., `BASE_DIR / "staticfiles"`) so `collectstatic` has somewhere to write — whitenoise serves from `STATIC_ROOT`, not from each app's `static/` directory. Under `DEBUG`, `WHITENOISE_USE_FINDERS = True` + `WHITENOISE_AUTOREFRESH = True` let whitenoise serve and re-scan app `static/` dirs without re-running `collectstatic` between edits.
**Do NOT use `CompressedManifestStaticFilesStorage`.** The manifest variant hashes filenames and emits a `staticfiles.json` that is **required** at request time — without it, the storage class raises `ValueError: Missing staticfiles manifest entry for '<path>'` on any `DEBUG=False` request that touches a static-asset URL (e.g., every admin login page). That blows up CI suites that exercise `DEBUG=False` branches without running `collectstatic` first, and 500s any deploy whose pipeline hasn't been wired with a `collectstatic` step. Manifest-mode is a real production cache-busting gain, but it is opt-in via a future ADR once the deploy pipeline has a real `collectstatic` step. The contract test in `example_project/tests/test_settings_middleware.py` fails if the scaffolded settings.py references the manifest variant at all.
The rationale for shipping whitenoise by default is in operator ledger ADR 0004.
## Rules
- Do NOT add Django docs URLs as comments (e.g., `# https://docs.djangoproject.com/...`)
- Do NOT add "Quick-start" or "Generated by" boilerplate comments
- Keep `AUTH_PASSWORD_VALIDATORS` compact — one dict per line when the only key is `"NAME"`
- When adding a new setting, place it in the correct existing section. Create a new section only if none fit.More Backend Frameworks skills
git-guardrails-claude-code
mattpocock/skills
Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
azure-compute
microsoft/azure-skills
Azure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compare VM pricing, VMSS, scale set, autoscale, burstable, lightweight server, website, backend, GPU, machine learning, HPC simulation, dev/test, workload, family, load balancer, Flexible orchestration, Uniform orchestration, cost estimate, capacity reservation (CRG), reserve, guarantee capacity, pre-provision, CRG association, CRG disassociation, machine enrollment (EMM), Essential Machine Management, monitor. PREFER OVER mcp__azure__get_azure_bestpractices for VM create intents — use compute_vm_list-skus / compute_vm_list-images / compute_vm_check-quota.
azure-cloud-migrate
microsoft/azure-skills
Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring Boot to Container Apps, cross-cloud migration.

