# Justfile for config # Task runner for Django development # Install just: https://github.com/casey/just # Default task: show available commands default: @just --list # Run development server dev: uv run python manage.py runserver # Run development server with custom host and port dev-server HOST="0.0.0.0" PORT="8000": uv run python manage.py runserver {{ HOST }}:{{ PORT }} # Create migrations for all apps makemigrations: uv run python manage.py makemigrations # Create migrations for specific app makemigrations-app APP: uv run python manage.py makemigrations {{ APP }} # Run all migrations migrate: uv run python manage.py migrate # Reset database (delete all migrations) reset-db: uv run python manage.py flush --noinput uv run python manage.py migrate # Create superuser createsuperuser: uv run python manage.py createsuperuser # Collect static files collectstatic: uv run python manage.py collectstatic --noinput # Run Django shell shell: uv run python manage.py shell # Run Django shell plus (IPython) shell-plus: uv run python manage.py shell_plus # Run tests test: uv run python manage.py test # Run tests with coverage test-coverage: uv run pytest --cov=. --cov-report=html --cov-report=term # Lint code with ruff lint: uv run ruff check . # Format code with ruff format: uv run ruff format . # Lint and format code style: uv run ruff check . uv run ruff format . # Check security issues check: uv run python manage.py check # Check security issues (production settings) check-deploy: uv run python manage.py check --deploy # Show all database migrations status showmigrations: uv run python manage.py showmigrations # Sync dependencies (uv equivalent of pip freeze) requirements: #!/usr/bin/env -S uv run python import tomllib from pathlib import Path pyproject = Path("pyproject.toml") if not pyproject.exists(): print("pyproject.toml not found") raise SystemExit(1) data = tomllib.loads(pyproject.read_text()) deps = data.get("project", {}).get("dependencies", []) Path("requirements.txt").write_text("\n".join(deps) + "\n") print("Generated requirements.txt from pyproject.toml") # Run all linting and checks ci: uv run ruff check . uv run ruff format --check . uv run python manage.py check # Start interactive shell shell-ipython: uv run python manage.py shell_plus # Clear all cache clear-cache: uv run python manage.py clear_cache # Show Django version version: uv run python manage.py version # Run database shell dbshell: uv run python manage.py dbshell # Start production server with gunicorn server: uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 # Start production server with gunicorn workers server-prod WORKERS="4": uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers {{ WORKERS }} # Start production server with gunicorn and reload on file changes server-watch: uv run gunicorn config.wsgi:application --bind 0.0.0.0:8000 --reload # Clean Python cache files clean: find . -type d -name "__pycache__" -exec rm -rf {} + find . -type f -name "*.pyc" -delete find . -type f -name "*.pyo" -delete find . -type f -name ".coverage" -delete find . -type d -name "*.egg-info" -exec rm -rf {} + rm -rf htmlcov/ rm -rf .pytest_cache/ # Pin dependencies in pyproject.toml using versions from uv.lock, keeping >= and extras pin-deps: #!/usr/bin/env -S uv run python import tomllib, re from pathlib import Path lock = Path("uv.lock") if not lock.exists(): print("uv.lock not found — run `uv sync` first") raise SystemExit(0) data = tomllib.loads(lock.read_text()) packages = {p["name"].lower(): p["version"] for p in data.get("package", [])} py = Path("pyproject.toml") lines = py.read_text().splitlines() pattern = re.compile(r'^(\s*)"([^"]+)"(,?)') out = [] for line in lines: m = pattern.match(line) if not m: out.append(line) continue indent, dep, comma = m.groups() base = dep extras = "" operator = ">=" version = None # extras: django[postgres] if "[" in base and "]" in base: before, after = base.split("[", 1) extras = "[" + after.split("]")[0] + "]" base = before # detect >= or == if ">=" in dep: operator = ">=" base, version = dep.split(">=") base = base.strip() elif "==" in dep: operator = "==" base, version = dep.split("==") base = base.strip() else: base = dep base_lower = base.lower() new_version = packages.get(base_lower) if new_version: new_dep = f'{base}{extras}{operator}{new_version}' line = f'{indent}"{new_dep}"{comma}' out.append(line) py.write_text("\n".join(out) + "\n") print("Pinned dependencies (>= preserved, extras preserved).") # Setup project for development (using uv) setup: uv sync just pin-deps uv run python manage.py migrate uv run python manage.py createsuperuser # Complete setup including static files setup-complete: uv sync uv run python manage.py migrate uv run python manage.py collectstatic --noinput uv run python manage.py createsuperuser # Install a new package install PACKAGE: uv add {{ PACKAGE }} # Install a dev package install-dev PACKAGE: uv add --dev {{ PACKAGE }} # Remove a package remove PACKAGE: uv remove {{ PACKAGE }}