Notas de lanzamiento de Django 5.1

Agosto 7, 2024

Bienvenido a Django 5.1!

Estas notas de lanzamiento cubren las nuevas características, así como algunas cambios incompatibles con lo anterior que debes tener en cuenta al actualizar desde Django 5.0 o versiones anteriores. Hemos comenzado el proceso de desactivación para algunas características <deprecated-features-5.1>.

Consulte la guía Cómo actualizar Django a una versión más reciente si estás actualizando un proyecto existente.

Compatibilidad con Python

Django 5.1 admite Python 3.10, 3.11, 3.12 y 3.13 (a partir de la versión 5.1.3). Recomendamos y solo oficialmente apoyamos la última versión de cada serie.

¿Qué hay de nuevo en Django 5.1

{% querystring %} etiqueta de plantilla

Django 5.1 introduce la {% querystring %} etiqueta de plantilla, simplificando la modificación de parámetros de consulta en URLs, lo que facilita generar enlaces que mantengan los parámetros de consulta existentes mientras se agregan o cambian específicos.

Por ejemplo, navegar por paginación y cadenas de consulta en plantillas puede ser engorroso. Considera este fragmento de plantilla que genera dinámicamente una URL para navegar a la siguiente página dentro de una vista paginada:

{# Linebreaks added for readability, this should be one, long line. #}
<a href="?{% for key, values in request.GET.iterlists %}
  {% if key != "page" %}
    {% for value in values %}
      {{ key }}={{ value }}&amp;
    {% endfor %}
  {% endif %}
{% endfor %}page={{ page.next_page_number }}">Next page</a>

Al cambiar a usar esta nueva etiqueta de plantilla, lo anterior se convierte mágicamente en:

<a href="{% querystring page=page.next_page_number %}">Next page</a>

Conexiones de pool PostgreSQL

Django 5.1 también introduce el soporte para la piscina de conexiones de PostgreSQL. Dado que el tiempo necesario para establecer una nueva conexión puede ser relativamente largo, mantener las conexiones abiertas puede reducir la latencia.

Para usar una piscina de conexiones con psycopg_, puedes establecer la opción "pool" dentro de OPTIONS para que sea un diccionario a ser pasado a ConnectionPool, o a True para utilizar los valores por defecto de ConnectionPool:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # ...
        "OPTIONS": {
            "pool": {
                "min_size": 2,
                "max_size": 4,
                "timeout": 10,
            }
        },
    },
}

Para requerir autenticación por defecto, utiliza el middleware LoginRequiredMiddleware.

La nueva clase LoginRequiredMiddleware redirecciona todas las solicitudes no autenticadas a una página de inicio de sesión. Las vistas pueden permitir solicitudes no autenticadas utilizando el nuevo decorador login_not_required().

LoginRequiredMiddleware respeta los valores login_url y redirect_field_name establecidos mediante el decorador login_required(), pero no admite la configuración de login_url o redirect_field_name a través de la clase LoginRequiredMixin.

Para habilitar esto, agrega "django.contrib.auth.middleware.LoginRequiredMiddleware" a tu configuración MIDDLEWARE.

Características menores

django.contrib.admin

django.contrib.auth

  • La cuenta de iteraciones predeterminada del hasheador de contraseña PBKDF2 se incrementa desde 720,000 a 870,000.

  • El paralelismo predeterminado del hasheador de contraseña ScryptPasswordHasher se incrementa desde 1 a 5, para seguir las recomendaciones de OWASP.

  • La nueva clase AdminUserCreationForm y la existente AdminPasswordChangeForm ahora admiten deshabilitar la autenticación basada en contraseña estableciendo una contraseña inválida al guardar el formulario. Esto está disponible en la interfaz de administración cuando se visita las páginas de creación de usuarios y cambio de contraseña.

  • Los decoradores login_required(), permission_required() y user_passes_test() ahora admiten envolver funciones de vistas asíncronas.

  • La traducción de los textos es la siguiente:

django.contrib.gis

django.contrib.postgres

  • BTreeIndex ahora admite el parámetro deduplicate_items.

django.contrib.sesiones

Base de datos

  • La opción "init_command" está ahora admitida en OPTIONS en SQLite para permitir especificar opciones de pragma para establecer al conectar.

  • La opción "transaction_mode" está ahora admitida en OPTIONS en SQLite para permitir especificar el comportamiento de transacciones de sqlite.

  • La opción "pool" está ahora admitida en OPTIONS en PostgreSQL para permitir utilizar pools de conexiones.

Información sobre errores

  • Para mejorar la accesibilidad, las páginas de error técnico 404 y 500 ahora utilizan elementos HTML de referencia para el encabezado, pie de página y área de contenido principal.

Almacenamiento de archivos

Formularios

  • Los cambios en la accesibilidad y el soporte de lectores de pantalla se han mejorado con la inclusión del atributo aria-describedby HTML en los fieldsets de formulario.

Comandos de Gestión

  • El comando makemigrations ahora muestra símbolos significativos para cada operación, destacando las categorías de operaciones <django.db.migrations.operations.base.OperationCategory>.

Migraciones

  • La nueva atributo Operation.category permite especificar una categoría de operación <django.db.migrations.operations.base.OperationCategory> utilizada por el comando makemigrations para mostrar un símbolo significativo para la operación.

Modelos

  • QuerySet.explain() ahora admite la opción generic_plan en PostgreSQL 16+.

  • RowRange ahora acepta enteros positivos como argumento start y enteros negativos como argumento end.

  • El nuevo argumento exclusion de RowRange y ValueRange permite excluir filas, grupos y empates de los marcos de ventana.

  • QuerySet.order_by() ahora admite la ordenación por transformaciones de anotación como claves JSONObject y índices ArrayAgg.

  • Las expresiones F() y OuterRef() que producen valores de tipo CharField, EmailField, SlugField, URLField o TextField pueden ahora ser sliced.

  • El nuevo argumento from_queryset de Model.refresh_from_db() y Model.arefresh_from_db() permite personalizar la consulta utilizada para recargar el valor de un modelo. Esto se puede utilizar para bloquear la fila antes de recargarla o seleccionar objetos relacionados.

  • La nueva atributo constraint_validation_compatible de Expression permite especificar que la expresión debe ser ignorada durante una validación de restricciones.

Plantillas

  • Los cambios en esta versión permiten a las etiquetas personalizadas establecer datos adicionales en el objeto Parser que luego estarán disponibles en la instancia de plantilla. Dichos datos pueden usarse, por ejemplo, por el cargador de plantillas o otros clientes de plantillas.

  • Ahora las motores de plantillas <field-checking> implementan un método check() que ya está registrado con el marco de trabajo de comprobación.

Pruebas

  • Las afirmaciones assertContains(), assertNotContains() y assertInHTML() ahora agregan pajares a los mensajes de error de las afirmaciones.

  • Las clases RequestFactory, AsyncRequestFactory, Client y AsyncClient admiten ahora el parámetro query_params, que acepta un diccionario de claves y valores de cadena de consulta. Esto permite establecer cadenas de consulta en cualquier método HTTP con más facilidad.

    self.client.post("/items/1", query_params={"action": "delete"})
    await self.async_client.post("/items/1", query_params={"action": "delete"})
    
  • La nueva afirmación SimpleTestCase.assertNotInHTML() permite probar que un fragmento HTML no está contenido en el pajareo dado de HTML.

  • Para garantizar la aislamiento de las pruebas, ya no se permiten conexiones a bases de datos dentro de hilos en SimpleTestCase.

Validadores

Cambios incompatibles con versiones anteriores en 5.1

django.contrib.gis

  • Se ha eliminado el soporte para PostGIS 2.5.

  • Se ha eliminado el soporte para PROJ < 6.

  • Soporte para GDAL 2.4 se ha eliminado.

  • GeoIP2 ya no abre tanto la base de datos de ciudad como la de país cuando se proporciona un camino de directorio, prefiriendo la base de datos de ciudad si está disponible. La base de datos de país es un subconjunto de la base de datos de ciudad y ambos no suelen ser necesarios. Si requieres el uso de la base de datos de país cuando estás en el mismo directorio que la base de datos de ciudad, pasa explícitamente el camino de la base de datos de país al constructor.

Soporte descartado para MariaDB 10.4

La asistencia de upstream para MariaDB 10.4 finaliza en junio de 2024. Django 5.1 admite MariaDB 10.5 y versiones superiores.

Soporte descartado para PostgreSQL 12

La documentación oficial de Django indica que el soporte upstream para PostgreSQL 12 termina en noviembre de 2024. Django 5.1 admite PostgreSQL 13 y versiones superiores.

Miscelánea

  • Para mejorar la accesibilidad, el filtro de la lista de cambios del administrador se renderiza ahora en una <nav> en lugar de un <div>.

  • Para mejorar la accesibilidad, el pie de página del administrador se renderiza ahora en una etiqueta <footer> en lugar de una <div>, y también se ha movido debajo del elemento <div id="main">.

  • Para mejorar la accesibilidad, el widget expansible utilizado para ModelAdmin.fieldsets y InlineModelAdmin.fieldsets, cuando el conjunto de campos tiene un nombre y utiliza la clase collapse, ahora incluye elementos <details> y <summary>.

  • El archivo de JavaScript collapse.js se ha eliminado ya que ya no es necesario en el sitio administrativo de Django.

  • SimpleTestCase.assertURLEqual() y assertInHTML() ahora agregan ": " al msg_prefix. Esto es consistente con el comportamiento de otras afirmaciones.

  • django.utils.text.Truncator utilizado por los filtros de plantilla truncatechars_html y truncatewords_html ahora utiliza clases que heredan de html.parser.HTMLParser. Esto resulta en una operación más robusta y rápida, pero pueden haber pequeñas diferencias en la salida.

  • La función no documentada django.urls.converters.get_converter() se ha eliminado.

  • La versión mínima soportada de SQLite aumenta desde 3.27.0 a 3.31.0.

  • FileField ahora lanza una FieldError cuando se guarda un archivo sin name.

  • La llamada a ImageField.update_dimension_fields(force=True) ya no se realiza después de guardar la imagen en almacenamiento. Si su backend de almacenamiento redimensiona imágenes, los campos width_field y height_field no coincidirán con el ancho y alto de la imagen.

  • La versión mínima soportada de asgiref aumenta desde 3.7.0 a 3.8.1.

  • Para mejorar el rendimiento, la acción administrativa delete_selected ahora utiliza QuerySet.bulk_create() cuando se crean múltiples objetos LogEntry. Como resultado, los señales pre_save y post_save para LogEntry no se envían cuando se eliminan múltiples objetos a través de esta acción administrativa.

Características deprecadas en 5.1

Miscelánea

  • Los métodos ModelAdmin.log_deletion() y LogEntryManager.log_action() están deprecados. Las clases hijas deben implementar ModelAdmin.log_deletions() y LogEntryManager.log_actions() en su lugar.

  • La traducción de los textos es la siguiente:

  • El método django.contrib.gis.geoip2.GeoIP2.coords() está descontinuado. Utiliza django.contrib.gis.geoip2.GeoIP2.lon_lat() en su lugar.

  • El método django.contrib.gis.geoip2.GeoIP2.open() está descontinuado. Utiliza el constructor GeoIP2 en su lugar.

  • Pasando argumentos posicionales a Model.save() y Model.asave() está descontinuado en favor de argumentos solo por palabra clave.

  • Establecer django.contrib.gis.gdal.OGRGeometry.coord_dim está descontinuado. Utiliza set_3d() en su lugar.

  • Sobreescribir conversores existentes con django.urls.register_converter() está descontinuado.

  • El argumento de palabra clave check de CheckConstraint está descontinuado en favor de condition.

  • La propiedad no documentada OS_OPEN_FLAGS de FileSystemStorage está descontinuada. Para permitir sobreescribir archivos en almacenamiento, establece la nueva opción allow_overwrite a True en su lugar.

  • El método get_cache_name() de FieldCacheMixin está descontinuado en favor de la propiedad cached cache_name.

Características eliminadas en 5.1

Estos características han alcanzado el final de su ciclo de deprecación y se eliminan en Django 5.1.

Consulte Características deprecadas en 4.2 para obtener detalles sobre estos cambios, incluyendo cómo eliminar el uso de estas características.

  • El método BaseUserManager.make_random_password() se elimina.

  • La opción Meta.index_together del modelo se elimina.

  • El filtro de plantilla length_is se elimina.

  • Se eliminan los hashers de contraseña django.contrib.auth.hashers.SHA1PasswordHasher, django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher y django.contrib.auth.hashers.UnsaltedMD5PasswordHasher.

  • Los modelos django.contrib.postgres.fields.CICharField, django.contrib.postgres.fields.CIEmailField y django.contrib.postgres.fields.CITextField se eliminan, excepto el soporte en migraciones históricas.

  • La mezcla de texto CIText del contribuyente de PostgreSQL se elimina.

  • Se eliminan las atributos map_width y map_height de la clase BaseGeometryWidget.

  • El método SimpleTestCase.assertFormsetError() se elimina.

  • La traducción es la siguiente:

  • Se elimina el soporte para pasar cadenas de JSON codificadas como literales a JSONField y consultas y expresiones asociadas.

  • Se elimina el soporte para pasar argumentos posicionales a Signer y TimestampSigner.

  • Las configuraciones DEFAULT_FILE_STORAGE y STATICFILES_STORAGE están eliminadas.

  • La función django.core.files.storage.get_storage_class() está eliminada.