6 puntos por GN⁺ 2025-12-05 | 1 comentarios | Compartir por WhatsApp
  • Se lanzó la versión 6.0 del framework web Django con soporte para Python 3.12 o superior, y una mejora sustancial en seguridad, plantillas y capacidades asíncronas.
  • Incluye nativamente Content Security Policy (CSP), lo que permite definir políticas para protegerse de ataques de inyección de contenido como XSS.
  • Con la funcionalidad Template Partials, se pueden definir secciones reutilizables dentro de los templates, mejorando la modularidad del código.
  • Se agregó el Background Tasks Framework para habilitar la ejecución de tareas asíncronas fuera del ciclo de solicitud-respuesta.
  • La adopción de una API de correo de Python más moderna, el fin del soporte de MariaDB 10.5 y el cambio del valor predeterminado de DEFAULT_AUTO_FIELD modernizan la compatibilidad de la versión.

Compatibilidad con Python

  • Django 6.0 es compatible con Python 3.12, 3.13 y 3.14, y solo da soporte oficial a las últimas versiones de cada rama.
  • Django 5.2.x es la última versión que admite Python 3.10 y 3.11.
  • A partir de Django 6.0 se recomienda que las apps de terceros dejen de soportar versiones anteriores a Django 5.2.

Novedades principales

Soporte de Content Security Policy (CSP)

  • Django incorporó el estándar CSP, reforzando la protección contra ataques de inyección de contenido como XSS.
    • ContentSecurityPolicyMiddleware, el context processor csp() y la configuración SECURE_CSP permiten definir políticas.
    • La configuración basada en diccionarios de Python permite construir políticas claras y seguras.
  • Es posible activar un modo de monitoreo con SECURE_CSP_REPORT_ONLY.
  • Se incluye un decorador para sobrescribir o desactivar la política por vista.

Template Partials

  • Se agregaron las etiquetas partialdef y partial para definir y reutilizar fragmentos dentro de templates.
  • Se puede referenciar directamente desde get_template(), render() y {% include %} usando la sintaxis template_name#partial_name.
  • Se proporciona una guía de migración para quienes usaban el paquete de terceros django-template-partials.

Background Tasks Framework

  • Django agrega un framework integrado para ejecutar tareas asíncronas.
    • Permite ejecutar tareas como envío de correos o procesamiento de datos fuera del ciclo de solicitud-respuesta HTTP.
    • Las tareas se definen con el decorador @task y se registran con enqueue().
  • El backend se configura mediante TASKS e incluye dos backends predeterminados para desarrollo y pruebas.
  • Django solo se encarga de crear y encolar tareas; su ejecución debe ser realizada por un worker externo.

Adopción de la API de correo más moderna de Python

  • La lógica de correo de Django se cambió al API de correo moderno de Python desde 3.6 (email.message.EmailMessage).
  • Las clases antiguas SafeMIMEText y SafeMIMEMultipart quedaron obsoletas.
  • El tipo de retorno de EmailMessage.message() cambió a una instancia de EmailMessage de Python.

Mejoras detalladas

Admin

  • Se aplicó el paquete de íconos Font Awesome Free 6.7.2.
  • Es posible personalizar el formulario de cambio de contraseña del admin mediante la propiedad AdminSite.password_change_form.
  • Se aplicaron íconos y estilos CSS dedicados a messages.DEBUG y messages.INFO.

Auth

  • Las iteraciones de hash PBKDF2 aumentaron de 1,000,000 a 1,200,000.

GIS

  • La propiedad GEOSGeometry.hasm permite verificar la presencia de una dimensión M.
  • La función Rotate permite rotar un ángulo específico.
  • La propiedad BaseGeometryWidget.base_layer permite personalizar proveedores de tiles.
  • En MariaDB 12.0.1+, se habilitan funciones como coveredby, isvalid, GeoHash y IsValid.
  • Al renderizar widgets se eliminó JavaScript inline; al personalizarlos puede ser necesario editar la plantilla.

PostgreSQL

  • Se agregaron expresiones Lexeme para reforzar el control del buscador de texto completo.
  • Se añadió el parámetro hints a operaciones de extensiones como CreateExtension.
  • Se agregaron comprobaciones del sistema para campos, índices y restricciones relacionados con django.contrib.postgres.

Staticfiles

  • ManifestStaticFilesStorage ahora garantiza una consistencia en el orden de rutas para reducir diferencias innecesarias.
  • El comando collectstatic muestra por defecto solo un resumen; los detalles aparecen a partir de --verbosity 2.

Varios

  • Se agregó soporte para el criollo haitiano.
  • Los comandos startproject y startapp crean automáticamente directorios inexistentes.
  • El comando shell importa automáticamente utilidades base como django.conf.settings.
  • Se agregó compatibilidad de serialización de zoneinfo.ZoneInfo en migraciones.
  • Se agregaron nuevas funciones de agregación como StringAgg y AnyValue.
  • AsyncPaginator y AsyncPage habilitan paginación asíncrona.
  • Se habilita soporte para múltiples encabezados de cookies HTTP/2 en entornos ASGI.
  • Se agregó la variable forloop.length en templates y se mejoró la etiqueta querystring.
  • DiscoverRunner ahora soporta pruebas paralelas con forkserver.

Cambios incompatibles

API de backend de base de datos

  • BaseDatabaseSchemaEditor y el backend de PostgreSQL dejaron de usar CASCADE al eliminar columnas.
  • Se cambiaron nombres de métodos, como return_insert_columns() a returning_columns().
  • Se habilita DatabaseFeatures.can_return_rows_from_update=True cuando se soporta UPDATE … RETURNING.

Deprecado

  • Se finalizó el soporte de MariaDB 10.5 (requiere 10.6 o superior).
  • Se dejó de dar soporte a Python por debajo de 3.12.
    • Versiones mínimas de librerías principales: aiosmtpd 1.4.5, bcrypt 4.1.1, Pillow 10.1.0, psycopg 3.1.12, entre otras.

Email

  • Se eliminaron los atributos mixed_subtype, alternative_subtype y encoding.
  • Debido a cambios internos, se requiere revisar las subclases personalizadas de EmailMessage.

Cambio del valor predeterminado de DEFAULT_AUTO_FIELD

  • El valor predeterminado cambió de AutoField a BigAutoField.
  • Los proyectos que no abordaron la advertencia de Django 3.2 (models.W042) deben agregar la configuración correspondiente.

Expresiones ORM

  • Los parámetros de retorno del método as_sql() deben ser una tupla.

Varios

  • Se agregó siempre un salto de línea al serializar JSON.
  • Se elevó la versión mínima de asgiref a 3.9.1.

Funcionalidades en desuso próximas

API de django.core.mail

  • En get_connection(), send_mail() y similares, los argumentos opcionales deben pasarse solo como argumentos con nombre.
  • Al crear EmailMessage y EmailMultiAlternatives, solo se permiten argumentos con nombre después de los primeros 4.

Varios

  • Se deprecó BaseDatabaseCreation.create_test_db(serialize); usa serialize_db_to_string() en su lugar.
  • Se deprecó StringAgg y OrderableAggMixin específicos de PostgreSQL.
  • Se prevé que en Django 7.0 el protocolo por defecto de urlize y urlizetrunc cambie a HTTPS.
  • ADMINS y MANAGERS ahora deben ser listas de cadenas de correo, en lugar de tuplas de (nombre, dirección).
  • Se deprecaron clases de correo como SafeMIMEText, SafeMIMEMultipart y BadHeaderError.

Características removidas

  • Se eliminó el soporte de argumentos posicionales de BaseConstraint.
  • Se eliminaron DjangoDivFormRenderer y Jinja2DivFormRenderer.
  • Se eliminó el soporte del driver de base de datos cx_Oracle.
  • El esquema predeterminado de forms.URLField cambió de "http" a "https".
  • Se eliminó el soporte de argumentos posicionales en Model.save() y Model.asave().
  • Se eliminaron ModelAdmin.log_deletion() y LogEntryManager.log_action().
  • Se eliminó el módulo django.utils.itercompat.
  • Se eliminaron los métodos GeoIP2.coords() y GeoIP2.open().
  • Se eliminaron ForeignObject.get_joining_columns() y sus métodos relacionados.

Django 6.0 fortaleció la seguridad, el procesamiento asíncrono y la adopción de una API moderna de correo para mejorar la estabilidad y escalabilidad del framework, y dejó en claro la migración a entornos con Python 3.12+.

1 comentarios

 
GN⁺ 2025-12-05
Opiniones de Hacker News
  • En una organización donde trabajé antes había una base de código “moderna” hecha con NodeJS+React y una app legacy de Django sobre Python 2.7 con casi 15 años de antigüedad
    Al principio me preocupaba que el código viejo fuera un dolor, pero en realidad fue todo lo contrario
    La app de Django era un gusto de manejar y ordenar el código fue realmente divertido. Cuando llegue el momento de reemplazarla con un nuevo rewrite en Go/React, creo que la voy a extrañar

    • No entiendo por qué querrían reemplazarla. Si no está rota, no hay necesidad de cambiarla
  • Felicidades al equipo de Django
    Durante mucho tiempo he mantenido una starter app de Django + Celery + Postgres + Redis + esbuild + Tailwind basada en Docker Compose, y hace poco la actualicé para Django 6.0
    Se puede ver en el repositorio de GitHub
    Todavía no incluí la configuración de CSP por defecto, pero planeo agregarla después de revisarla mejor

    • Iba a guardarlo en marcadores, pero descubrí que ya lo había guardado en diciembre de 2023
    • Los repositorios de Nick siempre son de primer nivel. Yo también los cito seguido en mi propio material. Gracias por compartirlos públicamente
    • Usé esta plantilla en un proyecto hace unos años y fue realmente excelente
    • Ver que hace poco se agregó uv me dio la impresión de que sigue manteniéndose de forma constante
  • La filosofía “batteries included” de Django encaja perfectamente con la generación de código por IA
    El panel de administración, el login, el restablecimiento de contraseña y otras funciones básicas ya vienen bien resueltas, así que la IA puede crear un sitio completo incluso con una base de código pequeña
    Como el código es compacto y claro, también es fácil que la IA lo mejore de forma iterativa

    • Una ventaja de Django es que tiene una estructura de código fácil de leer para humanos
      En vez de componentes gigantes, hay modelos y plantillas claras, así que también es más fácil revisar el código generado por IA
      Además, el admin de Django existe como una ground truth independiente, así que incluso si el frontend se rompe, todavía puedes manejar los datos
      Eso sí, es una pena que el ecosistema de Python no haya adoptado el modelo gevent. Si lo hubiera hecho, la transición a lo asíncrono habría sido mucho más fluida
    • Gracias a la estructura de INSTALLED_APPS de Django, es fácil agregar o quitar funciones por app
      Está mucho más integrado que frameworks de acoplamiento laxo como Flask o FastAPI
      Esa diferencia termina reduciendo una enorme cantidad de pequeñas molestias (papercuts)
    • He usado tanto Django como Rails, y al probar con Claude Code, Rails funcionó muchísimo mejor
      Reescribí una app vieja de .NET y Rails la convirtió casi a la perfección, pero Django tuvo dificultades
    • En realidad, Ruby on Rails lleva más tiempo ofreciendo por defecto cosas como CSP, background workers y otras funciones
    • Django se ha usado durante tantísimo tiempo en proyectos open source que la IA tiene muchísimo código de entrenamiento para aprender
  • La función de template partials de esta versión se ve bastante bien
    Pero el estado de las anotaciones de tipos (type annotations) sigue siendo incómodo
    django-stubs necesita un plugin de mypy, django-types es un fork para pyright pero no se sincroniza bien
    Y pylance además usa su propio fork
    Ojalá en la próxima versión al menos se incluyan oficialmente tipos básicos como HttpRequest, HttpResponse, View y Model

  • Gracias a Django, desarrollar para la web fue realmente divertido
    Aunque cambie a otros frameworks, al final siempre termino volviendo a Django. Fue una elección de la que nunca me arrepentí

    • A mí me pasó lo mismo con Ruby on Rails
      Aunque pruebe otros frameworks, siempre vuelvo por lo cómodo que es Rails
      Eso sí, me decepciona que Rails no tenga un Admin UI por defecto
    • Si miras solo el backend, Django es excelente, pero en el lado frontend sigue estando a nivel de la edad de piedra
      Si quieres un stack realmente full stack, es mejor mirar Laravel o Rails
    • Sinceramente, nunca entendí muy bien el encanto de Django
      Llevo haciendo web desde la era de PHP, y Django siempre me pareció más o menos equis
  • Django fue mi primer gran proyecto freelance, y todavía me hace sentir cómodo
    Probé varios enfoques experimentales, pero siempre funcionó bien. Gracias, Django

  • Llevo casi 15 años usando Django casi de manera exclusiva
    He probado muchos otros frameworks, pero ninguno se ha sentido tan natural en las manos como Django
    En esta versión agregaron el task framework, pero me decepciona que no incluya backend ni worker
    Preferiría que lo incluyeran ya completo en la próxima versión

    • Me pregunto si Django tiene pensado cruzar esa línea. Por la filosofía del framework, parece que valora mantener ese límite
    • No hay que dejar que lo perfecto sea enemigo de lo bueno. Al final, Django es un framework para “perfeccionistas con fecha de entrega”
  • Gracias a su enfoque batteries included, Django encaja en proyectos de cualquier tamaño
    Mis aplausos para el equipo y los contribuidores

  • Me pregunto cómo fue que entramos en la era de las SPA. Quisiera saber si fue simplemente por querer eliminar los loading spinners o si había una razón más profunda

    • Una de las razones principales fue la aparición de las apps móviles
      Al hacer que web, iOS y Android compartieran un mismo backend, el patrón SPA se extendió de forma natural
      Yo todavía hago SPA, pero algún día me gustaría encarar un proyecto grande con Django + htmx
    • Hace tiempo pasé a SPA mientras hacía visualización de datos con Angular
      Era atractivo que funcionara como una app sin recargar la página, pero en la práctica muchas veces igual hacía falta un hard refresh
      Aun así, me parece elegante la estructura que separa datos y presentación
    • La web originalmente fue creada para renderizar documentos, pero los usuarios querían apps
      Por eso siguieron los intentos de convertir documentos en apps usando JS
    • En la época en que internet era lento y la validación en el backend también lo era, se empezó agregando JS para la validación de formularios y luego la cosa se fue complicando
      Al final se separaron frontend y backend, y aparecieron contratos de API y procesos de validación
      Más adelante volvió la tendencia de integrar todo con server components, y justo ahí es donde estamos ahora
      Como ejemplo de formularios web a la antigua, se puede ver este enlace
    • A las plantillas como las de Django o Rails les faltaba seguridad de tipos
      Por eso terminé prefiriendo un proceso de build basado en TypeScript
  • Cada vez que uso Django, simplemente siento placer. Eso es todo.