
Django + PostgreSQL: conexión segura con .env (dotenv)
Conectaremos tu proyecto Django 5.2.x a PostgreSQL usando variables de entorno con
python-dotenv. Así evitamos exponer secretos y mantenemos entornos (dev/prod) aislados.1) Instala dependencias (driver y dotenv). Usa el binario de psycopg para simplificar.
- terminalBASH
source .venv/bin/activate # (Windows: .venv\Scripts\Activate.ps1) pip install "psycopg[binary]~=3.2" python-dotenv pip freeze > requirements.txt 2) Crea tu base de datos y usuario en PostgreSQL (si aún no existen).
- psqlSQL
-- Dentro de psql (o usa PGAdmin) CREATE ROLE mi_usuario WITH LOGIN PASSWORD 'mi_password'; ALTER ROLE mi_usuario SET client_encoding TO 'UTF8'; ALTER ROLE mi_usuario SET default_transaction_isolation TO 'read committed'; ALTER ROLE mi_usuario SET timezone TO 'America/Mexico_City'; CREATE DATABASE mi_db OWNER mi_usuario; GRANT ALL PRIVILEGES ON DATABASE mi_db TO mi_usuario; 3) Crea un archivo .env en la raíz del proyecto (junto a manage.py) con las variables para la conexión.
- terminalBASH
cat > .env << 'EOF' # --- DATABASE --- DB_NAME=mi_db DB_USER=mi_usuario DB_PASSWORD=mi_password DB_HOST=localhost DB_PORT=5432 # --- DJANGO --- DEBUG=True SECRET_KEY=pon-una-seed-larga-y-unica ALLOWED_HOSTS=127.0.0.1,localhost EOF 4) Carga .env en settings. Usa
python-dotenvyos.getenv. Asegúrate de importaros.- config/settings.pyPYTHON
# config/settings.py import os from pathlib import Path from dotenv import load_dotenv BASE_DIR = Path(__file__).resolve().parent.parent load_dotenv(BASE_DIR / ".env") DEBUG = os.getenv("DEBUG", "False").lower() == "true" SECRET_KEY = os.getenv("SECRET_KEY", "change-me") ALLOWED_HOSTS = [h.strip() for h in os.getenv("ALLOWED_HOSTS", "").split(",") if h.strip()] or ["127.0.0.1", "localhost"] DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": os.getenv("DB_NAME"), "USER": os.getenv("DB_USER"), "PASSWORD": os.getenv("DB_PASSWORD"), "HOST": os.getenv("DB_HOST", "localhost"), "PORT": os.getenv("DB_PORT", "5432"), # Opcional en producción (ej. Railway/Render/AWS RDS): # "OPTIONS": {"sslmode": "require"}, } } 5) Verifica que Django detecta la conexión (aplica migraciones base y ejecuta).
- terminalBASH
python manage.py check yes "" | python manage.py makemigrations # (no crea nada si no hay modelos nuevos) python manage.py migrate python manage.py runserver 8000 6) Prueba rápida con un modelo simple para confirmar escritura/lectura.
- core/models.pyPYTHON
# core/models.py from django.db import models class Ping(models.Model): creado = models.DateTimeField(auto_now_add=True) - terminalBASH
python manage.py makemigrations core python manage.py migrate python manage.py shell -c "from core.models import Ping; Ping.objects.create(); print(Ping.objects.count())" 7) Buenas prácticas para producción.
• Nunca subas
.enval repositorio (usa.gitignore).
• CambiaDEBUG=False, configuraALLOWED_HOSTSy añadesslmode=requirecuando tu proveedor lo pida.
• Usa un usuario de DB con permisos mínimos (no superuser) y rota credenciales si hay incidentes.
• Mantén backups automáticos y monitoreo de conexiones.8) Errores comunes y cómo resolverlos (rápido).
•
psycopg.OperationalError: connection refused: VerificaDB_HOST,DB_PORTy que PostgreSQL esté iniciado.
•password authentication failed: Usuario/clave opg_hba.confmal configurados.
• Migraciones atascadas: revisapython manage.py showmigrationsy asegura que la base apuntada es la correcta.
•.envno cargado: confirma la ruta enload_dotenv(BASE_DIR / ".env")y queos.getenvdevuelve valores.9) (Opcional) Variables de entorno del sistema/servidor. En contenedores o PaaS, define las keys (
DB_NAME,DB_USER, etc.) en el panel y omite el.env, o cópialo vía secretos (no en la imagen).Con esto tu Django queda conectado a PostgreSQL mediante variables de entorno gestionadas por dotenv. ¿Quieres que lo dejemos listo con
docker-compose(Django + Postgres + pgAdmin) y volúmenes persistentes?