Introducción Las Progressive Web Apps (PWA) combinan lo mejor de la web y de las apps nativas: cargan al instante, funcionan sin conexión y pueden instalarse en el dispositivo del usuario. Transformar tu proyecto Django en una PWA no es complicado, pero sí requiere atender a varios detalles. En este post recorreremos, paso a paso, los “tips” esenciales para lograrlo de forma clara y sin dolor de cabeza. Requisitos Previos
  • Django 4.x o superior
  • Navegador con soporte para Service Workers (todos los modernos)
  • Servidor HTTPS en producción (los Service Workers solo se registran en contexto seguro)
1. Instalar las dependencias básicas La ruta “manual” te da control total, pero si quieres acelerar el proceso, django-pwa o django-serviceworker hacen gran parte del trabajo pesado.
pip install django-pwa
En settings.py añades el paquete y la app estática:
INSTALLED_APPS = [ ... "django.contrib.staticfiles", "pwa", # <-- nuevo ]
2. Crear y exponer el manifest El manifest.json contiene metadatos para que el navegador “instale” tu app. Guárdalo en tu carpeta static y enlázalo en base.html.
{ "name": "Mi Django PWA", "short_name": "DjangoPWA", "start_url": "/", "display": "standalone", "scope": "/", "theme_color": "#0e4c92", "background_color": "#ffffff", "icons": [ { "src": "/static/img/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/static/img/icon-512.png", "sizes": "512x512", "type": "image/png" } ] }
En tu plantilla base:
<link rel="manifest" href="{% static 'manifest.json' %}">
3. Registrar el Service Worker El Service Worker intercepta peticiones y decide qué cachear. Crea static/sw.js:
self.addEventListener("install", event => { event.waitUntil( caches.open("v1").then(cache => cache.addAll([ "/", "/static/css/main.css", "/static/js/main.js", ])) ); }); self.addEventListener("fetch", event => { event.respondWith( caches.match(event.request).then(response => response || fetch(event.request) ) ); });
Luego regístralo en tu plantilla:
<script> if ("serviceWorker" in navigator) { window.addEventListener("load", () => { navigator.serviceWorker.register("{% static 'sw.js' %}"); }); } </script>
4. Ajustar cabeceras y seguridad
  • SECURE_SSL_REDIRECT = True en producción.
  • CSP: bloquea recursos externos no necesarios.
  • X-Frame-Options y Referrer-Policy coherentes.
5. Añadir estrategias de caché inteligentes No todo debe ir al mismo “bucket”. Mi combo favorito:
  • Cache First para assets estáticos y fuentes.
  • Stale-While-Revalidate para vistas HTML frecuentemente actualizadas.
  • Network First para endpoints críticos (API con datos frescos).
6. Habilitar modo offline “agradable” Sirve una página HTML mínima cuando la red falla:
self.addEventListener("fetch", event => { event.respondWith( fetch(event.request).catch(() => caches.match("/offline/")) ); });
7. Testear con Lighthouse Ejecuta Chrome DevTools ► Lighthouse. Apunta a una puntuación PWA > 90. Ajusta lo que falte (service worker activo, ratio de contraste, tiempos de carga). 8. Configurar despliegue CI/CD y versioning Cada build debe “romper” la caché vieja. Buen truco: inyecta el GIT_SHA en el nombre del Service Worker o en la versión de cache (caches.open("v{{ GIT_SHA }}")). Así evitas que los usuarios queden atascados con JS obsoleto. 9. Consigue ese icono “Add to Home Screen” Para que Chrome muestre el mini‑banner debes:
  • Tener HTTPS.
  • Tener manifest válido con start_url y icons de 192 y 512 px.
  • Service Worker con al menos un fetch o cache activo.
10. Bonus: Push Notifications Si tu app lo necesita, integra django-webpush. El flujo general:
  1. Generas claves VAPID.
  2. Registras permisos en el cliente.
  3. Envías notificación desde una view o un Celery task.
Conclusión Convertir tu Django en PWA es cuestión de añadir un par de ficheros estáticos, registrar un Service Worker y cuidar la caché. Mi opinión personal, Capi: vale mucho la pena. La sensación de “app nativa” mejora la retención y, con HTTPS+Service Worker bien configurado, ganas velocidad y resiliencia gratis. Empieza simple, itera, y pronto tu proyecto estará listo para ocupar un lugar de honor en la pantalla de inicio de tus usuarios. ¡Nos leemos en el próximo post y, como siempre, rompe esos logs antes de que te rompan a ti!