6 de abril de 2021
Bienvenido a Django 3.2!
Estas notas de lanzamiento cubren las nuevas características, así como algunos cambios incompatibles con lo anterior que desecharás estar al tanto cuando actualices Django 3.1 o una versión anterior. Hemos comenzado el proceso de desactivación para algunas características <deprecated-features-3.2>.
Consulte la guía Cómo actualizar Django a una versión más reciente si estás actualizando un proyecto existente.
Django 3.2 se designa como un lanzamiento con soporte a largo plazo. Recibirá actualizaciones de seguridad durante al menos tres años después de su lanzamiento. El soporte para el LTS anterior, Django 2.2, terminará en abril de 2022.
Django 3.2 admite Python 3.6, 3.7, 3.8, 3.9 y 3.10 (a partir de 3.2.9). Recomendamos y solo oficialmente apoyamos la última versión de cada serie.
AppConfig¶Los textos traducidos son:
Cuando el submódulo apps.py existe y define una sola clase de tipo AppConfig, Django utiliza automáticamente esa configuración, por lo que puedes eliminar default_app_config.
La variable default_app_config permitía declarar solo la ruta de la aplicación en INSTALLED_APPS (por ejemplo, 'django.contrib.admin') en lugar de la ruta del config de app (por ejemplo, 'django.contrib.admin.apps.AdminConfig'). Fue introducida por compatibilidad con el estilo anterior, con la intención de cambiar al estilo posterior, pero no sucedió.
Con la descubierta automática de AppConfig, default_app_config ya no es necesario. Como consecuencia, está desaconsejado.
Consultar Configuración de aplicaciones para obtener detalles completos.
Cuando defines un modelo, si no se define ningún campo en el modelo con primary_key=True, se agrega una clave primaria implícita. El tipo de esta clave primaria implícita puede ahora controlarse a través del parámetro de configuración DEFAULT_AUTO_FIELD y la propiedad AppConfig.default_auto_field . Ya no es necesario sobrescribir las claves primarias en todos los modelos.
Manteniendo el comportamiento histórico, el valor por defecto para DEFAULT_AUTO_FIELD es AutoField. A partir de la versión 3.2, nuevos proyectos se generan con DEFAULT_AUTO_FIELD configurado en BigAutoField. Además, nuevos apps se generan con AppConfig.default_auto_field configurado en BigAutoField. En una futura versión de Django, el valor por defecto de DEFAULT_AUTO_FIELD cambiará a BigAutoField.
Para evitar migraciones no deseadas en el futuro, establece explícitamente DEFAULT_AUTO_FIELD en AutoField:
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
o configúralo por aplicación de forma individual:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
default_auto_field = "django.db.models.AutoField"
name = "my_app"
en base a cada modelo:
from django.db import models
class MyModel(models.Model):
id = models.AutoField(primary_key=True)
En anticipación del cambio por defecto, un sistema de comprobación proporcionará una advertencia si no tienes una configuración explícita para DEFAULT_AUTO_FIELD.
Cuando cambias el valor de DEFAULT_AUTO_FIELD, las migraciones para la clave primaria de tablas existentes creadas automáticamente no pueden generarse actualmente. Consulta los documentos de DEFAULT_AUTO_FIELD para obtener detalles sobre cómo migrar tales tablas.
El nuevo argumento posicional de expresiones *expressions de la clase Index() permite crear índices funcionales sobre expresiones y funciones del motor de base de datos. Por ejemplo:
from django.db import models
from django.db.models import F, Index, Value
from django.db.models.functions import Lower, Upper
class MyModel(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
height = models.IntegerField()
weight = models.IntegerField()
class Meta:
indexes = [
Index(
Lower("first_name"),
Upper("last_name").desc(),
name="first_last_name_idx",
),
Index(
F("height") / (F("weight") + Value(5)),
name="calc_idx",
),
]
Índices funcionales se agregan a modelos utilizando la opción Meta.indexes.
pymemcache¶El nuevo back-end de caché django.core.cache.backends.memcached.PyMemcacheCache permite utilizar la biblioteca pymemcache <https://pypi.org/project/pymemcache/> para memcached. Se requiere pymemcache 3.4.0 o superior. Para obtener más detalles, consulte la documentación sobre caché en Django <topics/cache>.
El nuevo decorador display() permite agregar opciones a funciones de visualización personalizadas que se pueden utilizar con list_display o readonly_fields.
Likewise, el nuevo decorador de función action() permite agregar opciones a las funciones de acción con facilidad que se pueden utilizar con actions.
Al usar el decorador @display tiene la ventaja de poder utilizar el decorador @property cuando se necesitan especificar atributos en el método personalizado. Anteriormente era necesario utilizar la función property() en lugar de eso después de asignar los atributos requeridos al método.
Al usar decoradores tiene la ventaja de que estas opciones son más descubribles ya que pueden ser sugeridas por herramientas de completado en editores de código. Son meramente una comodidad y aún establecen los mismos atributos en las funciones bajo la capa.
django.contrib.admin¶ModelAdmin.search_fields permite ahora buscar contra frases entre comillas con espacios.
Los campos relacionados solo de lectura se renderizan ahora como enlaces navegables si los modelos objetivo están registrados en el admin.
El admin admite ahora temas y incluye un tema oscuro que está habilitado según las configuraciones del navegador. Consulte Soporte para temas para obtener más detalles.
ModelAdmin.autocomplete_fields respetan ahora ForeignKey.to_field y ForeignKey.limit_choices_to al buscar un modelo relacionado.
El admin instala ahora una vista final que redirige a la página de inicio de sesión a los usuarios no autenticados, independientemente de si la URL es válida en otro sentido. Esto protege contra un posible problema de privacidad de enumeración de modelos.
Aunque no se recomienda, puedes establecer el nuevo AdminSite.final_catch_all_view a False para deshabilitar la vista final.
django.contrib.auth¶La cuenta de iteraciones por defecto para el hasheador de contraseña PBKDF2 se incrementa desde 216,000 hasta 260,000.
La variante por defecto para el hasheador de contraseñas Argon2 se cambia a Argon2id. Se incrementan memory_cost y parallelism a 102,400 y 8 respectivamente para coincidir con los valores por defecto de argon2-cffi.
Aumentar memory_cost empuja la memoria requerida desde 512 KB hasta 100 MB. Esto sigue siendo bastante conservador pero puede provocar problemas en entornos con restricciones de memoria. Si es el caso, el hasheador existente se puede sobrescribir para reemplazar los valores por defecto.
La entropía de sal por defecto para los hasheadores de contraseñas Argon2, MD5, PBKDF2 y SHA-1 se incrementa a 128 bits en lugar de 71.
django.contrib.contenttypes¶El nuevo argumento absolute_max para la función generic_inlineformset_factory() permite personalizar el número máximo de formularios que pueden ser instanciados al proporcionar datos POST. Consulte Limitar el número máximo de formularios instanciados para obtener más detalles.
El nuevo argumento can_delete_extra para la función generic_inlineformset_factory() permite eliminar la opción de borrar formularios adicionales. Consulte can_delete_extra para obtener más información.
django.contrib.gis¶La método GDALRaster.transform() ahora admite SpatialReference.
La clase DataSource ahora admite pathlib.Path.
La clase LayerMapping ahora admite pathlib.Path.
django.contrib.postgres¶El nuevo atributo include de la clase ExclusionConstraint permite crear exclusiones cubiertas en PostgreSQL 12+.
El nuevo atributo opclasses de la clase ExclusionConstraint permite establecer clases de operadores de PostgreSQL.
El nuevo atributo JSONBAgg.ordering determina el orden de los elementos agrupados.
El nuevo atributo JSONBAgg.distinct determina si los valores agrupados serán distintos.
La operación CreateExtension ahora comprueba que la extensión ya existe en la base de datos y salta la migración si es así.
Las nuevas operaciones CreateCollation y RemoveCollation permiten crear y eliminar collaciones en PostgreSQL. Consulte Gestión de collaciones mediante migraciones para obtener más detalles.
Los lookups de ArrayField ahora permiten (no anidados) arreglos que contienen expresiones como lados derecho.
La nueva expresión OpClass() permite crear índices funcionales sobre expresiones con un operador personalizado. Consulte Índices funcionales para obtener más detalles.
Los nuevos atributos de la clase Sitemap: alternates, languages y x_default permiten generar mapas alternativos a versiones localizadas de tus páginas.
Los backends de bases de datos terceros pueden saltarse o marcar como fallas esperadas las pruebas en el conjunto de pruebas de Django utilizando los nuevos atributos DatabaseFeatures.django_test_skips y django_test_expected_failures.
Los textos traducidos son:
Las clases personalizadas de ExceptionReporter pueden ahora definir las propiedades html_template_path y text_template_path para sobreescribir los plantillas utilizados para renderizar informes de excepciones.
El nuevo callback FileUploadHandler.upload_interrupted() permite manejar subidas interrumpidas.
La nueva argumento absolute_max para formset_factory(), inlineformset_factory() y modelformset_factory() permite personalizar el número máximo de formularios que se pueden instanciar al proporcionar datos POST. Consulte la sección Limitar el número máximo de formularios instanciados para obtener más detalles.
La nueva argumento can_delete_extra para formset_factory(), inlineformset_factory() y modelformset_factory() permite eliminar la opción de borrar formularios adicionales. Consulte la sección can_delete_extra para obtener más información.
La clase BaseFormSet ahora informa un error que afecta al usuario, en lugar de levantar una excepción, cuando la forma de gestión está ausente o ha sido manipulada. Para personalizar este mensaje de error, pasa el argumento error_messages con la clave 'missing_management_form' al instanciar el conjunto de formularios.
Las propiedades week_format de WeekMixin y WeekArchiveView ahora admiten el formato de semana ISO 8601 '%V'.
La herramienta loaddata ahora admite fijos almacenados en archivos XZ (.xz) y LZMA (.lzma).
La herramienta dumpdata ahora puede comprimir datos en los formatos bz2, gz, lzma o xz.
La herramienta makemigrations ahora se puede llamar sin conexión a una base de datos activa. En ese caso, la comprobación de la historia de migraciones consistente se omite.
BaseCommand.requires_system_checks ahora admite la especificación de una lista de etiquetas. Se realizarán comprobaciones del sistema registradas en las etiquetas elegidas antes de ejecutar el comando. En versiones anteriores, se realizaban todas o ninguna de las comprobaciones del sistema.
Se actualiza el soporte para la salida en terminal coloreada en Windows. Se detectan automáticamente varios entornos de terminal modernos y se mejoran las opciones para habilitar el soporte en otros casos. Consulta Coloración sintáctica para obtener más detalles.
La nueva propiedad Operation.migration_name_fragment permite proporcionar un fragmento de nombre de archivo que se utilizará para nombrar una migración que contiene solo esa operación.
Las migraciones ahora admiten la serialización de objetos de ruta pura y concreta desde pathlib, y de instancias de os.PathLike.
La nueva opción no_key para QuerySet.select_for_update(), soportada en PostgreSQL, permite adquirir bloques de exclusión más débiles que no bloquean la creación de filas que hagan referencia a filas bloqueadas mediante una clave foránea.
La expresión When() ahora admite el uso del argumento condition con lookups.
Las nuevas atributos Index.include y UniqueConstraint.include permiten crear índices cubiertos y restricciones únicas cubiertas en PostgreSQL 11+.
El nuevo atributo UniqueConstraint.opclasses permite establecer clases de operadores de PostgreSQL.
El método QuerySet.update() ahora respeta la cláusula order_by() en MySQL y MariaDB.
La clase FilteredRelation() ahora admite relaciones anidadas.
La traducción de los textos es la siguiente:
La expresión Value() resuelve automáticamente su output_field a la clase de campo adecuada Field según el tipo del valor proporcionado para instancias de bool, bytes, float, int, str, datetime.date, datetime.datetime, datetime.time, datetime.timedelta, decimal.Decimal y uuid.UUID. Como consecuencia, resolver un output_field para funciones de base de datos y expresiones combinadas puede ahora fallar con tipos mixtos al usar Value(). Deberás establecer explícitamente el output_field en tales casos.
La nueva QuerySet.alias() permite crear alias reutilizables para expresiones que no necesitan ser seleccionadas pero se utilizan para filtrar, ordenar o como parte de expresiones complejas.
La nueva función Collate permite filtrar y ordenar por collaciones de base de datos especificadas.
El argumento field_name de QuerySet.in_bulk() ahora acepta campos distintos si solo se especifica un campo en QuerySet.distinct().
La nueva parámetro tzinfo de las funciones de base de datos TruncDate y TruncTime permite truncar fechas y horas en una zona horaria específica.
El nuevo argumento db_collation para CharField y TextField permite establecer la collación de base de datos para el campo.
Se agregó la función de base de datos Random.
Las funciones de agregación Funciones de agregación, F(), OuterRef() y otras expresiones ahora permiten utilizar transformaciones. Consulte Las expresiones pueden referenciar transformaciones para detalles.
El nuevo argumento durable para atomic() garantiza que los cambios realizados en el bloque atómico se comiten si el bloque sale sin errores. Un bloque atómico anidado marcado como duradero levantará una RuntimeError.
Se han agregado la función de base de datos JSONObject.
La nueva método django.core.paginator.Paginator.get_elided_page_range() permite generar un rango de páginas con algunos valores omitidos. Si hay un gran número de páginas, esto puede ser útil para generar un número razonable de enlaces de página en una plantilla.
Los encabezados de respuesta ahora se almacenan en HttpResponse.headers. Esto se puede utilizar en lugar de la interfaz original dict-like de los objetos HttpResponse. Ambas interfaces seguirán siendo compatibles. Consulte Estableciendo campos de encabezado para obtener más detalles.
El nuevo parámetro headers de HttpResponse, SimpleTemplateResponse y TemplateResponse permite establecer los encabezados de respuesta en la instantiación.
La configuración SECRET_KEY ahora se verifica para un valor válido al primer acceso, en lugar que cuando las configuraciones sean cargadas por primera vez. Esto permite ejecutar comandos de gestión que no dependen de SECRET_KEY sin necesidad de proporcionar un valor. Como consecuencia de esto, llamar a configure() sin proporcionar un valor válido para SECRET_KEY, y luego acceder a settings.SECRET_KEY ahora levantará una excepción ImproperlyConfigured.
Los nuevos métodos Signer.sign_object() y Signer.unsign_object() permiten firmar estructuras de datos complejas. Consulte Protegiendo estructuras de datos complejas para obtener más detalles.
También, las funciones signing.dumps() <django.core.signing.dumps> y loads() se convierten en atajos para los métodos TimestampSigner.sign_object() y unsign_object().
El método Signal.send_robust() <django.dispatch.Signal.send_robust> ahora registra excepciones.
La plantilla floatformat permite utilizar el sufijo g para forzar el agrupado por el THOUSAND_SEPARATOR del locale activo.
Los textos traducidos son:
Los objetos asignados a atributos de clase en TestCase.setUpTestData() están aislados ahora para cada método de prueba. Los objetos que no admiten la creación de copias profundas con copy.deepcopy() son ahora requeridos. Asignar objetos que no admiten deepcopy() está desaconsejado y se eliminará en Django 4.1.
DiscoverRunner habilita por defecto ahora faulthandler. Esto puede ser deshabilitado usando la opción test --no-faulthandler.
DiscoverRunner y el comando de administración test pueden rastrear ahora los tiempos, incluyendo la configuración de la base de datos y el tiempo total de ejecución. Esto puede ser habilitado usando la opción test --timing.
Client preserva ahora la cadena de consulta de solicitud cuando sigue redirecciones 307 y 308.
El nuevo método TestCase.captureOnCommitCallbacks() captura las funciones de llamada pasadas a transaction.on_commit() en una lista. Esto permite probar tales llamadas sin usar la clase lenta TransactionTestCase.
TransactionTestCase.assertQuerysetEqual() admite ahora comparaciones directas contra otro conjunto de consultas en lugar de estar restringido a comparaciones contra una lista de representaciones de cadena de objetos cuando se utiliza el valor predeterminado para el argumento transform.
La nueva función depth del django.utils.timesince.timesince() y django.utils.timesince.timeuntil() permite especificar el número de unidades temporales adyacentes a devolver.
Los validadores integrados ahora incluyen el valor proporcionado en el argumento params de una levantada ValidationError. Esto permite mensajes de error personalizados utilizar el placeholder %(value)s.
El operador de igualdad de la clase ValidationError ignora ahora el orden de los argumentos messages y params.
Esta es la traducción de los textos:
La nueva propiedad DatabaseFeatures.introspected_field_types reemplaza estas características:
can_introspect_autofield
can_introspect_big_integer_field
can_introspect_binary_field
can_introspect_decimal_field
can_introspect_duration_field
can_introspect_ip_address_field
can_introspect_positive_integer_field
can_introspect_small_integer_field
can_introspect_time_field
introducidos_big_auto_campo_tipo
introducido_pequeño_auto_campo_tipo
introducido_bloqueo_de_campo_tipo
Para habilitar el soporte para índices cubiertos (Index.include) y restricciones únicas cubiertas (UniqueConstraint.include), establezca DatabaseFeatures.supports_covering_indexes a True.
Los backends de bases de datos tercerizados deben implementar el soporte para collaciones de base de datos en campos CharFields y TextFields o establecer DatabaseFeatures.supports_collation_on_charfield y DatabaseFeatures.supports_collation_on_textfield a False. Si las collaciones no deterministas no están soportadas, establezca supports_non_deterministic_collations a False.
DatabaseOperations.random_function_sql() se ha eliminado en favor de la nueva función de base de datos Random.
DatabaseOperations.date_trunc_sql() y DatabaseOperations.time_trunc_sql() ahora aceptan el argumento opcional tzname para truncar en un horario específico.
DatabaseClient.runshell() ahora recibe argumentos y un diccionario opcional con variables de entorno al cliente de línea de comandos subyacente desde el método DatabaseClient.settings_to_cmd_args_env(). Los backends de bases de datos tercerizados deben implementar DatabaseClient.settings_to_cmd_args_env() o sobrescribir DatabaseClient.runshell().
Los backends de bases de datos tercerizados deben implementar el soporte para índices funcionales (Index.expressions) o establecer DatabaseFeatures.supports_expression_indexes a False. Si COLLATE no es parte del statement CREATE INDEX, establezca DatabaseFeatures.collate_as_index_expression a True.
django.contrib.admin¶Los textos traducidos son:
La nueva vista de captura general de la administración romperá los patrones de URL que se rutean después de las URLs de la administración y coinciden con el prefijo de URL de la administración. Puedes ajustar el orden de tus URL o, si es necesario, establecer AdminSite.final_catch_all_view a False, deshabilitando la vista de captura general. Consulta Qué hay de nuevo en Django 3.2 para obtener más detalles.
Los archivos JavaScript minimizados ya no se incluyen con la administración. Si requieres estos archivos sean minimizados, considera utilizar una aplicación de terceros o una herramienta de compilación externa. Los archivos JavaScript minimizados embutidos que se incluyen con la administración (por ejemplo, jquery.min.js) todavía están incluidos.
ModelAdmin.prepopulated_fields ya no elimina las palabras de parada en inglés, como 'a' o 'an'.
django.contrib.gis¶Se ha eliminado el soporte para PostGIS 2.2.
El back-end Oracle ahora clona polígonos (y colecciones geométricas que contienen polígonos) antes de reorientarlos y guardarlos en la base de datos. Ya no se mutan en su lugar. Puedes notarlo si usas los polígonos después de que un modelo se guarde.
El soporte upstream para PostgreSQL 9.5 termina en febrero de 2021. Django 3.2 admite PostgreSQL 9.6 y superior.
La fecha límite del soporte upstream para MySQL 5.6 es abril de 2021. Django 3.2 admite MySQL 5.7 y superior.
Django ahora admite zonas horarias no pytz, como el módulo de zona horaria zoneinfo de Python 3.9+ y su backport.
La función no documentada SpatiaLiteOperations.proj4_version() se renombró a proj_version().
slugify() ahora elimina las barras diagonales y guiones bajos en los extremos.
Los filtros de plantilla intcomma y intword ya no dependen del parámetro USE_L10N.
Se eliminó el soporte para argon2-cffi < 19.1.0.
Las claves de caché ya no incluyen el idioma cuando la internacionalización está deshabilitada (USE_I18N = False) y la localización está habilitada (USE_L10N = True). Después de actualizar a Django 3.2 en tales configuraciones, la primera solicitud a cualquier valor previamente cacheado será un error de caché.
ForeignKey.validate() ahora utiliza _base_manager en lugar de _default_manager para verificar que las instancias relacionadas existen.
Cuando una aplicación define una clase AppConfig en un módulo apps.py, Django ahora utiliza esta configuración automáticamente, incluso si no está habilitada con default_app_config. Establezca default = False en la clase AppConfig si necesita evitar este comportamiento. Consulte Qué hay de nuevo en Django 3.2 para obtener más detalles.
Instanciar un modelo abstracto ahora lanza TypeError.
Los argumentos de palabra clave a setup_databases() son ahora solo palabras clave.
La traducción de los textos es la siguiente:
Ahora django.test.utils.TestContextDecorator utiliza addCleanup() para que se llamen las limpiezas registradas en el método setUp() antes de TestContextDecorator.disable().
La clase SessionMiddleware ahora lanza una excepción SessionInterrupted en lugar de SuspiciousOperation cuando se destruye una sesión en una solicitud concurrente.
El operador de igualdad para la clase django.db.models.Field ahora distingue correctamente las instancias de campos heredados entre modelos. Además, el ordenamiento de dichos campos está definido.
La función no documentada django.core.files.locks.lock() ahora devuelve False si el archivo no puede ser bloqueado, en lugar de lanzar BlockingIOError.
El mecanismo de restablecimiento de contraseña ahora invalida los tokens cuando se cambia la dirección de correo electrónico del usuario.
La orden :djadmin:`makemessages` comando ya no procesa locales inválidos especificados utilizando la opción :option:`makemessages --locale`, cuando contienen guiones (“-”``).
El campo de formulario django.contrib.auth.forms.ReadOnlyPasswordHashField ahora está disabled por defecto. Por lo tanto, UserChangeForm.clean_password() ya no es necesario que devuelva el valor inicial.
Las operaciones de caché cache.get_many(), get_or_set(), has_key(), incr(), decr(), incr_version(), y decr_version() ahora manejan correctamente los valores None almacenados en el caché, del mismo modo que cualquier otro valor, en lugar de comportarse como si la clave no existiera.
Debido a una limitación del python-memcached, se mantiene el comportamiento anterior para el backend de caché desaconsejado MemcachedCache.
La versión mínima de SQLite admitida se incrementa desde la 3.8.3 hasta la 3.9.0.
CookieStorage ahora almacena mensajes en el formato compatible con la especificación RFC 6265. La compatibilidad con cookies que utilizan el formato antiguo permanece hasta Django 4.1.
La versión mínima soportada de asgiref se incrementa desde 3.2.10 hasta 3.3.2.
Asignar objetos que no admiten la creación de copias profundas con copy.deepcopy() a atributos de clase en TestCase.setUpTestData() está descontinuado.
Usar un valor booleano en :attr:.BaseCommand.requires_system_checks está descontinuado. Utiliza '__all__' en lugar de True, y [] (una lista vacía) en lugar de False.
El argumento whitelist y la atributo domain_whitelist de EmailValidator están descontinuados. Utiliza allowlist en lugar de whitelist, y domain_allowlist en lugar de domain_whitelist. Es posible que debas renombrar whitelist en las migraciones existentes.
La variable de configuración de la aplicación default_app_config está descontinuada debido a la descubierta automática de AppConfig. Consulte Qué hay de nuevo en Django 3.2 para obtener más detalles.
Automáticamente llamar repr() sobre una consulta en TransactionTestCase.assertQuerysetEqual(), cuando se compara con valores de cadena, está descontinuado. Si necesitas el comportamiento anterior, establece explícitamente transform a repr.
El back-end django.core.cache.backends.memcached.MemcachedCache está deprecado ya que python-memcached tiene algunos problemas y parece no estar mantenido. Utiliza django.core.cache.backends.memcached.PyMemcacheCache o django.core.cache.backends.memcached.PyLibMCCache en su lugar.
El formato de mensajes utilizado por django.contrib.messages.storage.cookie.CookieStorage es diferente al formato generado por versiones antiguas de Django. El soporte para el formato antiguo permanece hasta Django 4.1.
may 31, 2026