4 puntos por GN⁺ 2025-12-11 | 1 comentarios | Compartir por WhatsApp
  • Django 6.0, que celebra su 20.º aniversario, es una versión importante que mejora de forma significativa áreas clave como plantillas, tareas en segundo plano, seguridad y correo electrónico
  • La función Template partials facilita la reutilización de código dentro de las plantillas y refuerza la integración con herramientas como htmx
  • Se agregó el nuevo framework de Tasks, que permite ejecutar trabajos en segundo plano fuera del ciclo de solicitud-respuesta HTTP
  • Content Security Policy (CSP) ahora viene integrada por defecto, lo que simplifica la defensa contra ataques de inyección de contenido como XSS
  • La modernización de la API de correo electrónico, las mejoras en el ORM y la ampliación de las claves primarias mejoran notablemente la experiencia de desarrollo y la escalabilidad

Resumen de Django 6.0

  • Django 6.0 es una nueva versión del framework web de Python que continúa 20 años de evolución
  • Los cambios principales se centran en cuatro áreas clave: plantillas, trabajos en segundo plano, seguridad y manejo de correo electrónico
  • Participaron numerosos contribuidores de la comunidad de desarrolladores, y aquí se resumen las mejoras principales con base en las notas oficiales de la versión

Herramienta django-upgrade

  • Al actualizar proyectos existentes desde Django 5.2 o versiones anteriores, se puede usar la herramienta django-upgrade para convertir código automáticamente
  • Incluye cinco fixers automáticos relacionados con Django 6.0 y resuelve algunas advertencias de forma automática

Template partials

  • Se añadió la función de definición de fragmentos de plantilla ({% partialdef %}), que permite reducir la duplicación de código y reutilizarlo dentro de las plantillas
    • Se puede llamar varias veces al mismo partial definido dentro de la misma plantilla
    • Con la opción inline, se puede definir y renderizar al mismo tiempo
  • La función de renderizado parcial permite renderizar de forma independiente solo un partial específico
    • En el ejemplo, se usa htmx para actualizar periódicamente la parte view_count
    • Al agregar #partial_name a la URL, se puede renderizar solo una parte específica
  • Esta función se integró en Django a través de un proyecto de Google Summer of Code y evoluciona a partir del paquete existente django-template-partials

Framework de Tasks

  • Se añadió a Django un nuevo framework de Tasks para ejecutar trabajos en segundo plano
    • Permite ejecutar código fuera del ciclo de solicitud-respuesta HTTP
    • Puede usarse para trabajos asíncronos como envío de correos, procesamiento de datos y generación de reportes
  • Los trabajos se definen con el decorador @task y se pueden poner en cola con Task.enqueue()
  • Los backends incluidos por defecto son ImmediateBackend y DummyBackend para desarrollo,
    y con el paquete django-tasks se puede usar DatabaseBackend para ejecución basada en SQL DB
  • El worker de tareas se ejecuta con el comando db_worker, y el estado puede verificarse mediante los logs
  • Esta función surgió de una idea iniciada en Wagtail y se integró en Django después de la propuesta DEP 0014

Soporte para Content Security Policy (CSP)

  • Django 6.0 ofrece soporte nativo para el estándar CSP, reforzando la defensa contra ataques de inyección de contenido como XSS
    • Se activa agregando ContentSecurityPolicyMiddleware a MIDDLEWARE
    • La política puede configurarse con SECURE_CSP y SECURE_CSP_REPORT_ONLY
  • Incluye seguridad basada en nonce, por lo que se puede agregar el atributo nonce="{{ csp_nonce }}" a las etiquetas <script> y <style>
    • En cada solicitud se genera un nonce aleatorio y solo se ejecutan recursos confiables
  • CSP se propuso en 2004 y hasta ahora se había implementado mediante el paquete django-csp; en esta versión pasa a estar integrado oficialmente

Actualización de la API de correo electrónico

  • La lógica de manejo de correo de Django se migró a la API moderna de correo electrónico de Python 3.6
    • Internamente usa la clase email.message.EmailMessage
    • Las interfaces existentes send_mail() y EmailMessage se mantienen sin cambios
  • La nueva API ofrece ventajas como menos errores, mayor seguridad y mejor manejo de archivos adjuntos inline
  • Con objetos MIMEPart se pueden agregar fácilmente adjuntos inline como imágenes dentro del cuerpo HTML
  • Este cambio fue propuesto en 2024 y se fusionó después de ocho meses de desarrollo

Restricción de argumentos posicionales en la API de correo

  • En la API de django.core.mail, algunos parámetros ahora solo aceptan argumentos con nombre
    • Si se pasan como posicionales argumentos opcionales como fail_silently, se genera una advertencia
    • Es una medida orientada a mejorar la legibilidad y el mantenimiento
  • Se puede corregir automáticamente con el fixer mail_api_kwargs de django-upgrade

Ampliación del auto import en Shell

  • Se amplió la función de importación automática de modelos introducida en Django 5.2,
    y ahora también importa automáticamente settings, connection, models, functions, timezone
  • La lista de auto imports puede verse con ./manage.py shell -v 2
  • Esto mejora la comodidad en desarrollo y reduce código repetitivo

Mejora del ORM: actualización dinámica de campos al hacer save()

  • Los campos GeneratedField o basados en expresiones ahora se actualizan automáticamente después de save()
    • Se reflejan de inmediato en bases de datos que soportan la cláusula RETURNING (SQLite, PostgreSQL, Oracle)
    • En MySQL y MariaDB se actualizan automáticamente mediante carga diferida
  • Esto mejora la eficiencia al permitir usar valores actualizados de inmediato sin consultas adicionales

Función de agregación universal StringAgg

  • La función de agregación StringAgg ya puede usarse en todos los backends de base de datos
    • Devuelve una cadena con los valores de entrada unidos por un delimitador (delimiter)
    • Antes era una función exclusiva de PostgreSQL, pero ahora puede usarse directamente desde django.db.models
  • El delimitador puede especificarse con la expresión Value()

BigAutoField como valor predeterminado

  • El valor por defecto de DEFAULT_AUTO_FIELD cambió a BigAutoField
    • Usa claves primarias enteras de 64 bits para prevenir el agotamiento de Primary Key
    • En proyectos nuevos se aplica automáticamente sin configuración adicional
  • Esto simplifica la configuración introducida en Django 3.2 y reduce boilerplate

Mejoras en plantillas

  • Se añadió la variable forloop.length, que permite consultar la longitud total dentro de un bucle
    • Se usa con el formato {{ forloop.counter }}/{{ forloop.length }}
  • Mejoras en la etiqueta de plantilla querystring
    • Agrega ? automáticamente cuando el mapeo está vacío para mantener un comportamiento consistente en los enlaces
    • Soporta la combinación de múltiples argumentos de mapeo para facilitar la composición de parámetros de consulta

Cierre

  • En Django 6.0 participaron 174 contribuidores,
    e incluye numerosas optimizaciones y correcciones de errores
  • La actualización mejora en general la seguridad, mantenibilidad y experiencia de desarrollo (DX)
  • En las notas oficiales de la versión pueden consultarse cambios adicionales

1 comentarios

 
GN⁺ 2025-12-11
Comentarios de Hacker News
  • Llevo varios años usando Django de forma intermitente en la empresa. En general me gusta, pero el ORM todavía me sigue pareciendo difícil
    Django es un framework con opiniones fuertes, así que apenas ahora entendí que hay que seguir la “forma Django”.
    El problema es que tengo que manejar múltiples bases de datos de varias áreas del negocio, así que siempre termino sufriendo para adaptarme a sus particularidades.
    Al final lo resuelvo desactivando managed, importando el esquema con inspectdb y luego borrando manualmente las tablas que no quiero exponer en la web.
    Para aplicaciones web nuevas, Django sigue siendo la mejor opción

    • De acuerdo. Pero el flujo de trabajo de migraciones de BD todavía deja algo que desear
      Django no guarda el estado del esquema junto con el código, así que cada vez que ejecuta un comando de BD tiene que inferir el estado actual.
      Definir el estado de la BD a partir del código de los modelos tiene limitaciones inherentes.
      Yo prefiero más el enfoque de Rails, donde las migraciones se construyen con comandos explícitos de BD y luego se montan los modelos encima
    • Me pregunto si estás usando el soporte de múltiples bases de datos de Django
    • Probé Aldjemy en un proyecto pequeño, y resolvía bastante bien combinaciones complejas de consultas que con el ORM de Django son difíciles
    • Llevo más de 10 años usando Django y el ORM me parece “decente”. En algún momento hubo intención de cambiar a SQLAlchemy, pero no valía la pena.
      La interfaz de Manager confunde al principio, pero la herramienta de migraciones es realmente excelente
    • Configurar views o materialized views a través del ORM ayuda muchísimo al rendimiento.
      Así obtienes a la vez la flexibilidad del tuning en SQL y la comodidad de Django.
      Eso sí, no hay que olvidar crearlas dentro del script de migración
  • Me encanta que Django vaya mejorando de forma constante con cada release.
    La versión 6.0 en particular se ve interesante porque trae muchas funciones útiles.
    Eso de que una tecnología confiable tiene que ser aburrida es falso. Así es como debería evolucionar

    • Yo también lo uso desde la época pre-1.0 y todavía me encanta.
      Ahora vivo cerca del lugar donde nació Django.
      Y de paso, desde ayer estoy buscando trabajo, así que si buscan a un desarrollador Django con experiencia, contáctenme (oldspiceap@gmail.com)
  • El código y el blog de Adam siempre valen la pena leerlos.
    Tengo curiosidad por ver cómo evoluciona el framework de tasks.
    Aunque sí me dio un poco de pena que mencionaran al excelente Django-Q2 junto con Celery

    • Soy el autor. Gracias por el elogio, y mencioné Celery solo por su popularidad ;)
    • Celery no es perfecto, pero es la mejor opción disponible.
      Tiene muchos bugs, pero su base de usuarios es tan grande que es raro encontrarte con un problema por primera vez.
      He manejado de forma estable decenas de millones de mensajes al día con la combinación Celery + RabbitMQ.
      Sigue siendo una solución que vale la pena considerar primero
    • He usado Celery durante varios años; me gustaría saber qué fue lo problemático y cómo mejora eso Django Q2.
      En otros stacks también usamos Kafka, pero eso ya es para casos de uso de otro nivel
    • Me pregunto por qué dicen que Celery es “terrible”
  • Llevo usando Django unos 5 o 6 años, y aunque la ventaja de “incluye todo” es clara, en general se siente pesado

  • La función de template partials se ve buena.
    Una de las razones por las que React se volvió popular fue la reutilización de código, y parece que Django también va en esa dirección

    • La clave de la reutilización y la composición en React no es la plantilla, sino que todo son funciones
    • Esta función tiene mucho valor especialmente cuando se usa con HTMX. HTMX necesita muchas plantillas parciales
    • React no ofrece simples plantillas, sino componentes que encapsulan estado
    • Yo también probé partials en mi blog mientras testeaba Django 6
      El ejemplo está en este código
    • Me sorprende que Django haya añadido una función así hasta 2025
  • Yo uso principalmente Odoo, pero también he trabajado un poco con Django y Celery.
    Como alguien que usa bastante el módulo OCA queue de Odoo,
    siempre me he preguntado por qué Django no aprovecha la funcionalidad de LISTEN/NOTIFY de Postgres.
    Quizá solo sea porque no conozco tanto el ecosistema de Django

  • Template Partials y HTMX se sienten como la versión Django de Rails View Components + Stimulus.
    También da gusto ver soporte oficial para Tasks

    • El renderizado de partials en Rails puede verse en la guía oficial
    • Me pregunto si para usar Tasks en producción también hay que usar django-tasks
  • Uso Django desde la época de la versión 1.x, desde antes de que existiera el ORM.
    De verdad me sorprende que apenas ahora se haya añadido ejecución de tasks.
    No lo digo como crítica, solo me parece una evolución interesante

    • De hecho eso es refrescante. Django no se apresura con las funciones, sino que las implementa bien.
      Solo incluye cada función cuando ya está suficientemente probada, y se enfoca en LTS y en la estabilidad de la API.
      Gracias a eso, cuando sale una nueva versión casi nunca hace falta reescribir toda la aplicación
    • En realidad Django ya incluía ORM desde la versión 0.95.
      En ese entonces era simple, pero durante bastante tiempo no hacía falta usar SQL puro
  • La discusión adicional sigue en este hilo

  • Como usar Django con HTMX me resultaba muy incómodo por el tema de las plantillas por componente,
    terminé creando yo mismo una librería de componentes basada en Python: Compone.
    Puede usarse no solo con Django sino con cualquier framework web de Python, y ofrece una experiencia de desarrollo mucho más agradable