.gitignore for Django

.env *.log *.pot *.mo db.sqlite3 media/ !**/static/**/media/ staticfiles/

A Django .gitignore is Python’s, plus the files a running site writes: the local db.sqlite3, uploads under media/, the staticfiles/ that collectstatic gathers, logs, compiled translations, and .env. Those are the key lines the tool writes for Django picked with Python, .env coming from the Python block; the file has 65 lines once two duplicates are dropped.

What the blocks ignore

  • Python: bytecode, virtual environments, packaging output, test caches and .env.
  • Database: db.sqlite3 and its -journal, -shm and -wal files, plus any *.sqlite3.
  • Runtime files: media/, for uploads under MEDIA_ROOT, and staticfiles/, a common STATIC_ROOT. !**/static/**/media/ keeps an app’s own static/<app>/media/ folder.
  • Translations: *.pot templates and compiled *.mo files; the .po files you edit stay.
  • Logs and backups: *.log, *.bak, *.backup.

In a scratch repository with this file, git check-ignore -v -n --no-index names the line that matched each path, or prints :: when none did:

::	shop/migrations/0001_initial.py
.gitignore:84:*.sqlite3	db.sqlite3
.gitignore:76:media/	media/avatars/me.png
::	shop/static/shop/media/logo.png
.gitignore:80:staticfiles/	staticfiles/admin/css/base.css
::	shop/locale/de/LC_MESSAGES/django.po
.gitignore:66:*.mo	shop/locale/de/LC_MESSAGES/django.mo
.gitignore:30:.env	.env
::	config/local_settings.py

db.sqlite3 is reported against *.sqlite3 on line 84 rather than its own line 71: the last matching line decides.

Never ignore migrations

Django’s documentation says migration files are designed to be committed and distributed with the app’s code. Ignoring migrations/ means every machine generates its own, and they stop matching the history a shared database has applied. Commit them, along with your lockfile.

Compiled translations

Ignoring *.mo means every deploy runs compilemessages, which needs GNU gettext on that machine. If yours doesn’t have it, commit the compiled files with a line after the template:

.gitignore:87:!**/locale/**/*.mo	shop/locale/de/LC_MESSAGES/django.mo

That works because locale/ isn’t excluded. Under media/ or staticfiles/ it wouldn’t: Git never looks inside an excluded folder.

Settings with secrets

The template ignores .env, but not local_settings.py; if your settings import one, add it as a custom line. If db.sqlite3 or .env was committed before the file existed, untrack it, keeping it on disk, and commit:

git rm --cached db.sqlite3 .env
git commit -m "Stop tracking the local database and .env"

A committed .env stays in the history, so rotate whatever secrets it held.

Editor and OS files

PyCharm’s .idea/ and .DS_Store come from your machine. Pick the JetBrains template, or keep them in a global ignore file:

git config --global core.excludesFile ~/.gitignore_global

Try it in the Gitignore Generator

In the file: Python, Django

.gitignore

2 templates · 65 pattern lines · 2 duplicates dropped
# Python
# Bytecode cache written next to the source
__pycache__/
*.py[cod]
*$py.class
# Compiled extension modules built in place
*.so
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
# Left at the root by a virtualenv or buildout made there; anchored, so a lib/ further down, such as src/lib/, stays
/lib/
/lib64/
parts/
sdist/
/var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
pip-log.txt
pip-delete-this-directory.txt
.Python
# Local environment variables, read by python-dotenv and often holding secrets
.env
# Virtual environments: env, venv, .venv, ENV and the .bak variants
env/
venv/
.venv/
ENV/
env.bak/
venv.bak/
# Files PyInstaller writes before it builds an executable
*.manifest
*.spec
.pytest_cache/
.mypy_cache/
.ruff_cache/
.tox/
.nox/
.dmypy.json
dmypy.json
# Output of the Pyre and Pytype type checkers
.pyre/
.pytype/
cython_debug/
# IPython profile and history, when it writes into the project
profile_default/
ipython_config.py
# Data files from coverage.py, pytest-cov and friends
.coverage
coverage.xml
htmlcov/
# Checkpoints Jupyter writes next to every notebook
.ipynb_checkpoints/

# Django
*.log
# Translation templates; the .po files next to them are the ones you edit
*.pot
*.mo
*.pyc
*.pyo
*.pyd
# The local database, and its journal files
db.sqlite3
db.sqlite3-journal
db.sqlite3-shm
db.sqlite3-wal
# Uploads, written at runtime
media/
# An app's own static media/ folder is kept
!**/static/**/media/
# Collected static files
staticfiles/
# Editor and deploy backups
*.bak
*.backup
*.sqlite3
  • ✓Not ignored: no line in this file matches "/shop/migrations/0001_initial.py".

Lines are applied top to bottom, and the last one that matches wins — which is why a line of your own can overrule a template.

Runs in your browser. Nothing you enter is sent anywhere.