4 de abril de 2017
Bienvenido a Django 1.11!
Estas notas de lanzamiento cubren las nuevas características, así como algunos cambios incompatibles con la retrocesión que desecharás estar al tanto cuando actualices Django 1.10 o versiones anteriores. Hemos comenzado el proceso de desactivación para algunas características <deprecated-features-1.11>.
Consulte la guía Cómo actualizar Django a una versión más reciente si estás actualizando un proyecto existente.
Django 1.11 está designada como una lanzamiento con soporte a largo plazo. Recibirá actualizaciones de seguridad por lo menos durante tres años después de su lanzamiento. El soporte para el LTS anterior, Django 1.8, terminará en abril de 2018.
Django 1.11 requiere Python 2.7, 3.4, 3.5, 3.6 o 3.7 (a partir de 1.11.17). Recomendamos y solo oficialmente apoyamos la última versión de cada serie.
La serie Django 1.11.x es la última que soporta Python 2. La próxima versión mayor, Django 2.0, solo soportará Python 3.4+.
A diferencia de versiones anteriores de Django, las advertencias de desactivación propias de Django ya no se muestran por defecto. Esto es consistente con el comportamiento predeterminado de Python.
Esta modificación permite que las aplicaciones terceras apoyen tanto Django 1.11 LTS como Django 1.8 LTS sin tener que agregar código para evitar advertencias de deprecación.
Después del lanzamiento de Django 2.0, sugerimos a los autores de aplicaciones terceras que abandonen el soporte para todas las versiones de Django anteriores a 1.11. En ese momento, deberías poder ejecutar las pruebas de tu paquete utilizando python -Wd para que las advertencias de deprecación aparezcan. Después de realizar las correcciones de advertencia de deprecación, tu aplicación debería ser compatible con Django 2.0.
El nuevo módulo django.db.models.indexes contiene clases que facilitan la creación de índices de base de datos. Los índices se agregan a los modelos utilizando la opción Meta.indexes.
La clase Index crea un índice b-tree, como si hubieras utilizado db_index en el campo del modelo o index_together en la clase Meta del modelo. También permite definir el orden (ASC/DESC) para las columnas del índice.
Para facilitar la personalización de los widgets, ahora se hace el rendimiento de formularios utilizando el sistema de plantillas en lugar de Python. Consulta La API de renderizado de formularios.
Puede que debas ajustar cualquier widget personalizado que hayas escrito debido a unos pocos cambios incompatibles con la versión anterior <template-widget-incompatibilities-1-11>.
Subquery¶Los textos traducidos son:
django.contrib.admin¶La propiedad ModelAdmin.date_hierarchy puede ahora hacer referencia a campos en las relaciones.
El nuevo método ModelAdmin.get_exclude() permite especificar los campos excluidos según la solicitud o instancia de modelo.
La plantilla popup_response.html puede ahora ser sobrescrita por aplicación, por modelo o estableciendo la propiedad ModelAdmin.popup_response_template.
django.contrib.auth¶El recuento de iteraciones predeterminado para el algoritmo de hash de contraseña PBKDF2 se incrementa en un 20%.
Las vistas basadas en clases LoginView y LogoutView sustituyen a las vistas funcionales login() y logout() obsoletas.
Las vistas basadas en clases PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView y PasswordResetCompleteView sustituyen a las vistas funcionales password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() y password_reset_complete() obsoletas.
La nueva propiedad post_reset_login para la vista PasswordResetConfirmView permite loguear automáticamente a un usuario después de una contraseña restablecida con éxito. Si tienes múltiples AUTHENTICATION_BACKENDS configurados, utiliza la propiedad post_reset_login_backend para elegir cuál utilizar.
Para evitar la posibilidad de que se filtre un token de restablecimiento de contraseña a través del encabezado HTTP Referer (por ejemplo, si la página de restablecimiento incluye una referencia a CSS o JavaScript alojados en otro dominio), la vista PasswordResetConfirmView (pero no la vista funcionaria password_reset_confirm() obsoleta) almacena el token en sesión y redirige a sí misma para presentar el formulario de cambio de contraseña al usuario sin el token en la URL.
La función update_session_auth_hash() ahora rota la clave de sesión para permitir que un cambio de contraseña invalide las cookies de sesión robadas.
El nuevo atributo success_url_allowed_hosts para LoginView y LogoutView permite especificar un conjunto de hosts que son seguros para redireccionar después del inicio de sesión y la salida.
Se han agregado validadores de contraseña help_text a UserCreationForm.
La solicitud HttpRequest se pasa ahora a authenticate(), que a su vez la pasa al backend de autenticación si acepta un argumento request.
El señal user_login_failed() ahora recibe un argumento request.
La clase PasswordResetForm admite modelos de usuario personalizados que utilizan un campo de correo electrónico con el nombre algo diferente a 'email'. Establezca la propiedad CustomUser.EMAIL_FIELD al nombre del campo.
La función get_user_model() se puede llamar ahora en tiempo de importación, incluso en módulos que definen modelos.
django.contrib.contenttypes¶Cuando se detectan tipos de contenido obsoletos en el comando remove_stale_contenttypes, ahora hay una lista de objetos relacionados como auth.Permissions que también serán eliminados. Anteriormente, solo se listaban los tipos de contenido (y este mensaje era después de migrate en lugar de en un comando separado).
django.contrib.gis¶Los nuevos métodos GEOSGeometry.from_gml() y OGRGeometry.from_gml() permiten crear geometrías a partir de GML.
Se ha agregado soporte para la búsqueda con el operador dwithin en SpatiaLite.
La traducción de los textos es la siguiente:
Las herramientas de formulario basadas en OpenLayers ahora utilizan OpenLayers.js desde https://cdnjs.cloudflare.com, que es más adecuado para el uso en producción que la fuente antigua https://openlayers.org/. También se actualizan para utilizar OpenLayers 3.
Las migraciones de PostGIS pueden cambiar ahora las dimensiones de los campos.
Se ha agregado la capacidad de pasar los parámetros size, shape y offset al crear objetos GDALRaster.
Se ha agregado el soporte para SpatiaLite a las funciones IsValid, MakeValid y la consulta de búsqueda isvalid.
Se ha agregado el soporte para Oracle a las funciones AsGML, BoundingCircle, IsValid y la consulta de búsqueda isvalid.
django.contrib.postgres¶El nuevo argumento distinct para StringAgg determina si los valores concatenados serán distintos.
Las nuevas clases GinIndex y BrinIndex permiten crear índices GIN y BRIN en la base de datos.
El campo JSONField de django.contrib.postgres.fields acepta un nuevo parámetro encoder para especificar una clase personalizada para codificar tipos de datos no soportados por el encoder estándar.
La nueva mezcla CIText y la operación de migración CITextExtension permiten utilizar la extensión citext de PostgreSQL para consultas insensibles a mayúsculas. Se proporcionan tres campos: CICharField, CIEmailField y CITextField.
La traducción de los textos es la siguiente:
Los campos del modelo HStoreField y los campos del formulario HStoreField permiten almacenar valores nulos.
Los backends de Memcached ahora pasan el contenido de OPTIONS como argumentos clave a los constructores de clientes, lo que permite un control más avanzado del comportamiento del cliente. Consulte la documentación sobre argumentos de caché <cache_arguments> para obtener ejemplos.
Los backends de Memcached ahora permiten definir múltiples servidores como una cadena delimitada por comas en LOCATION, lo que facilita el uso con servicios terceros que utilizan cadenas similares en variables de entorno.
Se agregó la configuración CSRF_USE_SESSIONS para permitir almacenar el token CSRF en la sesión del usuario en lugar de en una cookie.
Se agregó el argumento skip_locked a QuerySet.select_for_update() en PostgreSQL 9.5+ y Oracle para ejecutar consultas con FOR UPDATE SKIP LOCKED.
Se agregó la configuración TEST['TEMPLATE'] para permitir que los usuarios de PostgreSQL especifiquen un template para crear la base de datos de prueba.
La función QuerySet.iterator() ahora utiliza cursor server-side en PostgreSQL. Esta característica transfiere parte del carga de memoria del trabajador (utilizada para almacenar resultados de consultas) a la base de datos y podría aumentar el uso de memoria de la base de datos.
Se agregó soporte para MySQL para la opción 'isolation_level' en OPTIONS para permitir especificar el nivel de aislamiento de transacción <mysql-isolation-level>. Para evitar posibles pérdidas de datos, se recomienda cambiar desde el nivel por defecto de MySQL, repeatable read, a read committed.
Se agregó soporte para cx_Oracle 5.3.
Agregó la configuración EMAIL_USE_LOCALTIME para permitir enviar encabezados de fecha SMTP en la zona horaria local en lugar de en UTC.
Ahora los métodos EmailMessage.attach() y attach_file() caen en el tipo de MIME application/octet-stream cuando se especifica contenido binario que no puede ser decodificado como UTF-8 para una anexión con tipo de MIME text/*.
Ahora que tiene los métodos readable(), writable() y seekable(), puede ser manipulado por io.TextIOWrapper.
El nuevo atributo empty_value en CharField, EmailField, RegexField, SlugField, y URLField permite especificar el valor de Python a utilizar para representar «vacío».
La nueva método Form.get_initial_for_field() devuelve los datos iniciales para un campo de formulario.
Formateo de números y la configuración NUMBER_GROUPING admiten agrupaciones no uniformes de dígitos.
La nueva opción loaddata --exclude permite excluir modelos y aplicaciones mientras se carga datos de fijos.
La nueva opción :option:`diffsettings –default permite especificar un módulo de configuración diferente a la configuración predeterminada de Django para comparar con ella.
app_labels argumentos ahora limitan la salida de la opción –plan del comando showmigrations.
Se han agregado funcionalidades de serialización para objetos uuid.UUID.
Se ha agregado soporte para valores llamables en el argumento defaults de las funciones QuerySet.update_or_create() y get_or_create().
La clase ImageField ahora tiene un validador por defecto validate_image_file_extension. (Este validador se ha movido a la clase de campo en Django 1.11.2.)
Se han agregado funcionalidades de truncamiento de tiempo a las funciones Trunc.
Se ha agregado la función ExtractWeek para extraer la semana de los campos DateField y DateTimeField, y se ha expuesto a través del lookup week.
Se ha agregado la función TruncTime para truncar el campo DateTimeField a su componente de hora, y se ha expuesto a través del lookup time.
Se han agregado funcionalidades de expresiones en las funciones QuerySet.values() y values_list().
Se han agregado funcionalidades de expresiones de consulta en lookups que toman múltiples argumentos, como range.
Ahora puedes utilizar la opción unique=True con la clase FileField.
Se han agregado los parámetros nulls_first y nulls_last a las funciones Expression.asc() y desc() para controlar el ordenamiento de valores nulos.
Los textos traducidos son:
Se han agregado QuerySet.union(), intersection() y difference().
Se ha agregado QueryDict.fromkeys().
La clase CommonMiddleware establece ahora el encabezado de respuesta Content-Length para respuestas no de transmisión.
Se ha agregado la configuración SECURE_HSTS_PRELOAD para permitir agregar la directiva preload al encabezado Strict-Transport-Security.
La clase ConditionalGetMiddleware agrega ahora el encabezado ETag a las respuestas.
El nuevo atributo django.core.serializers.base.Serializer.stream_class permite personalizar la clase de flujo por defecto en subclases.
El codificador utilizado por el serializador JSON se puede personalizar pasando un argumento cls a la función serializers.serialize().
La clase DjangoJSONEncoder serializa ahora objetos de tipo timedelta (usados por DurationField).
La función mark_safe() se puede utilizar como decorador.
La traducción de los textos es la siguiente:
El etiqueta regroup devuelve ahora tuplas nombradas en lugar de diccionarios, por lo que puedes desempaquetar el objeto del grupo directamente en un bucle, e.g. {% for grouper, list in regrouped %}.
Se ha agregado la etiqueta resetcycle de plantillas para permitir reiniciar la secuencia de la etiqueta cycle de plantillas.
Puedes especificar ahora directorios específicos para un determinado Cargador de archivos.
Se ha agregado el método DiscoverRunner.get_test_runner_kwargs() para permitir personalizar los argumentos de palabra clave pasados al ejecutor de pruebas.
Se ha agregado la opción test --debug-mode para ayudar a depurar fallas de prueba estableciendo el parámetro DEBUG en True.
Las nuevas funciones django.test.utils.setup_databases() (movidas desde django.test.runner) y teardown_databases() facilitan la creación de ejecutores de pruebas personalizados.
Se ha agregado soporte para unittest.TestCase.subTest() cuando se utiliza la opción test --parallel.
DiscoverRunner ahora ejecuta las comprobaciones del sistema al inicio de una ejecución de pruebas. Sustituye el método DiscoverRunner.run_checks() si deseas deshabilitar eso.
Se ha agregado la clase FileExtensionValidator para validar extensiones de archivo y validate_image_file_extension para validar archivos de imagen.
django.contrib.gis¶Para simplificar la base de código y porque es más fácil instalar que cuando contrib.gis se lanzó por primera vez, GDAL ahora es una dependencia requerida para GeoDjango. En versiones anteriores, solo era necesario para SQLite.
Se ha eliminado contrib.gis.maps ya que interfiere con una versión retirada de la API de Google Maps y parece no estar mantenida. Si lo estás utilizando, háganoslo saber.
El operador de igualdad de GEOSGeometry ahora también compara SRID.
Los widgets basados en OpenLayers ahora utilizan OpenLayers 3, y los templates gis/openlayers.html y gis/openlayers-osm.html han sido actualizados. Verifique su proyecto si subclasa estos widgets o extiende los templates. Además, los nuevos widgets funcionan de manera diferente a los antiguos. En lugar de utilizar una barra de herramientas en el widget, haz clic para dibujar, haz clic y arrastra para mover la mapa, y haz clic y arrastra un punto/verga/canto para moverlo.
Se ha dejado de apoyar SpatiaLite < 4.0.
Se ha dejado de apoyar GDAL 1.7 y 1.8.
Los widgets en contrib.gis.forms.widgets y el widget administrativo OpenLayersWidget utilizan la API de renderizado de formularios :doc:` </ref/forms/renderers>` en lugar de loader.render_to_string(). Si está utilizando un template de widget personalizado, asegúrese de que su renderizador de formularios pueda localizarlo. Por ejemplo, podría utilizar el TemplatesSetting renderer.
django.contrib.archivos_estáticos¶Puede que collectstatic fallen durante la post-procesamiento cuando se utiliza una almacenamiento de archivos estáticos hasheados si existe un bucle de referencia (por ejemplo, 'foo.css' referencia a 'bar.css' que a su vez referencia a 'foo.css') o si la cadena de archivos que se refieren a otros archivos es demasiado profunda para resolver en varias pasadas. En el último caso, aumente el número de pasos utilizando ManifestStaticFilesStorage.max_post_process_passes.
Cuando se utiliza ManifestStaticFilesStorage, los archivos estáticos no encontrados en el manifiesto en tiempo de ejecución ahora levantan un ValueError en lugar de devolver la ruta sin cambios. Puede revertir a la antigua conducta estableciendo ManifestStaticFilesStorage.manifest_strict a False.
Esta es la traducción de los textos:
Se agrega el método DatabaseOperations.time_trunc_sql() para apoyar la truncación del campo TimeField. Acepta argumentos lookup_type y field_name y devuelve la SQL apropiada para truncar el campo de tiempo dado field_name a un objeto de tiempo con solo la especificidad dada. El argumento lookup_type puede ser 'hora', 'minuto' o 'segundo'.
Se agrega el método DatabaseOperations.datetime_cast_time_sql() para apoyar la búsqueda time. Acepta argumentos field_name y tzname y devuelve la SQL necesaria para convertir un valor de fecha a un valor de tiempo.
Para habilitar el soporte para FOR UPDATE SKIP LOCKED, establece DatabaseFeatures.has_select_for_update_skip_locked = True.
La nueva característica DatabaseFeatures.supports_index_column_ordering especifica si una base de datos permite definir la ordenación de columnas en índices. El valor por defecto es True y el método DatabaseIntrospection.get_constraints() debe incluir un clave 'orders' en cada uno de los diccionarios devueltos con una lista de valores 'ASC' y/o 'DESC' correspondientes a la ordenación de cada columna en el índice.
inspectdb ya no llama al método DatabaseIntrospection.get_indexes() que está descontinuado. Los backends de bases de datos personalizados deben asegurarse de devolver todos los tipos de índices mediante DatabaseIntrospection.get_constraints().
Se renombra la característica ignores_quoted_identifier_case a ignores_table_name_case para reflejar con mayor precisión cómo se utiliza.
Se agrega el argumento de palabra clave name al método DatabaseWrapper.create_cursor(self, name=None) para permitir el uso de cursor del lado del servidor en backends que lo soporten.
El soporte upstream para PostgreSQL 9.2 termina en septiembre de 2017. Como consecuencia, Django 1.11 establece a PostgreSQL 9.3 como la versión mínima que oficialmente admite.
El soporte para PostGIS 2.0 también se ha eliminado ya que PostgreSQL 9.2 es la última versión que lo admite.
También, la versión mínima admitida de psycopg2 se incrementa desde 2.4.5 a 2.5.4.
LiveServerTestCase se une a puerto cero¶En lugar de tomar un rango de puertos e iterar para encontrar un puerto libre, LiveServerTestCase se une a puerto cero y confía en el sistema operativo para asignar un puerto libre. La variable de entorno DJANGO_LIVE_TEST_SERVER_ADDRESS ya no se utiliza, y como tampoco se utiliza, la opción manage.py test --liveserver se ha eliminado.
Si necesitas unir LiveServerTestCase a un puerto específico, usa el atributo port agregado en Django 1.11.2.
django.contrib.auth y i18n¶LoginView, LogoutView (y sus equivalentes basados en funciones, que están desaconsejados), y set_language() protegen a los usuarios contra ser redirigidos a URLs next no HTTPS cuando la aplicación está ejecutándose sobre HTTPS.
QuerySet.get_or_create() y update_or_create() validan argumentos¶Para evitar que los errores de escritura pasen silenciosamente, get_or_create() y update_or_create() comprueban que sus argumentos son campos del modelo. Esto debería ser incompatibilidad hacia atrás sólo en el hecho de que podría exponer un error en tu proyecto.
pytz es una dependencia requerida y se ha eliminado el soporte para settings.TIME_ZONE = None¶Para simplificar el manejo de zonas horarias en Django, pytz es ahora una dependencia requerida. Se instala automáticamente junto con Django.
Se ha eliminado el soporte para settings.TIME_ZONE = None ya que no se utiliza comúnmente y su utilidad es cuestionable. Si deseas detectar automáticamente la zona horaria basada en la zona horaria del sistema, puedes utilizar tzlocal:
from tzlocal import get_localzone
TIME_ZONE = get_localzone().zone
Esto funciona de manera similar a settings.TIME_ZONE = None, excepto que también establece os.environ['TZ']. Si hay un caso de uso donde no puedas adaptar tu código para establecer una zona horaria, háznoslo saber <https://groups.google.com/g/django-developers/c/OAV3FChfuPM/discussion>.
<p class="help"> se reemplaza con un tag <div> para permitir incluir listas dentro del texto de ayuda.
Los campos de solo lectura están envueltos en <div class="readonly">...</div> en lugar de <p>...</p> para permitir cualquier tipo de HTML como contenido del campo.
Se han eliminado algunas clases no documentadas en django.forms.widgets:
SubWidget
RendererMixin, ChoiceFieldRenderer, RadioFieldRenderer,
CheckboxFieldRenderer
ChoiceInput, RadioChoiceInput, CheckboxChoiceInput
Se ha eliminado el método no documentado Select.render_option().
Se ha eliminado el método Widget.format_output(). Utiliza en su lugar una plantilla de widget personalizada.
Los valores de los widgets, como las opciones del elemento <select>, se localizan ahora si settings.USE_L10N=True. Puedes revertir a la antigua comportamiento con plantillas de widget personalizadas que utilizan el etiqueta de plantilla localize para desactivar la localización.
django.template.backends.django.Template.render() prohíbe un contexto no dict¶Para compatibilidad con múltiples motores de plantillas, django.template.backends.django.Template.render() (devuelto por las API de carga de plantilla de alto nivel como loader.get_template()) debe recibir un diccionario de contexto en lugar de Context o RequestContext. Si estabas pasando cualquiera de las dos clases, pasa un diccionario en su lugar – lo que hace es compatible con versiones antiguas de Django.
Para mejorar la velocidad al aplicar migraciones, se retrasa el renderizado de modelos relacionados hasta una operación que los necesite (por ejemplo RunPython). Si tienes una operación personalizada que trabaja con clases o instancias de modelo desde el argumento from_state en database_forwards() o database_backwards(), debes renderizar estados del modelo utilizando el método clear_delayed_apps_cache() como se describe en writing your own migration operation.
El cambio para hacer que .QuerySet.iterator() utilice cursor de servidor en PostgreSQL impide ejecutar Django con PgBouncer en modo de agrupación de transacciones. Para permitirlo nuevamente, utiliza la configuración DISABLE_SERVER_SIDE_CURSORS (agregada en Django 1.11.1) en DATABASES.
See transacción-pooling-servidor-cursor para más discusión.
Si no hay elementos en el feed con la atributo pubdate o updateddate, SyndicationFeed.latest_post_date() ahora devuelve la fecha y hora actual de UTC, en lugar de una fecha sin información de zona horaria.
Los fallos CSRF se registran en el logger django.security.csrf en lugar de django.request.
La validación de ALLOWED_HOSTS ya no está deshabilitada cuando se ejecutan las pruebas. Si tu aplicación incluye pruebas con nombres de host personalizados, debes incluir esos nombres de host en ALLOWED_HOSTS. Consulta temas-pruebas-avanzadas-múltiples-hosts.
Al utilizar la clave foránea (por ejemplo 'campo_id') en ModelAdmin.list_display, se muestra el ID del objeto relacionado. Elimina el sufijo _id si deseas mantener el comportamiento antiguo de la representación como cadena del objeto.
En las formas de modelo, CharField con null=True ahora almacena NULL para los valores en blanco en lugar de cadenas vacías.
En Oracle, Model.validate_unique() ya no verifica las cadenas vacías como únicas ya que la base de datos interpreta el valor como NULL.
Si sobreescribes AbstractUser y redefinies clean(), asegúrate de que llame a super(). BaseUserManager.normalize_email() se llama en una nueva AbstractUser.clean() método para aplicar la normalización en casos como la validación de modelos.
EmailField y URLField ya no aceptan el argumento strip. Elimínalo porque no tiene efecto en versiones antiguas de Django, ya que estos campos siempre eliminan los espacios en blanco.
Las atributos checked y selected renderizados por widgets de formularios ahora utilizan la sintaxis booleana HTML5 en lugar de XHTML’s checked='checked' y selected='selected'.
RelatedManager.add(), remove(), clear(), y set() ahora limpian la caché de prefetch_related().
Para evitar una posible pérdida de configuraciones guardadas, setup_test_environment() ahora lanza una excepción si se llama por segunda vez antes de llamar a teardown_test_environment().
Se ha eliminado la alias no documentada DateTimeAwareJSONEncoder para DjangoJSONEncoder (renombrado en Django 1.0).
El cargador de plantillas cached template loader ahora está habilitado si no se especifica OPTIONS['loaders'] y OPTIONS['debug'] es False (la última opción tiene el valor por defecto de DEBUG). Esto podría ser incompatibilidad hacia atrás si tienes algunos etiquetas de plantilla que no son seguras en hilos.
Ya no se produce la advertencia para eliminar tipos de contenido caducados después de ejecutar el comando migrate. Utiliza el nuevo comando remove_stale_contenttypes en su lugar.
El widget del administrador para IntegerField utiliza type="number" en lugar de type="text".
Los encabezados HTTP condicionales ahora se parsean y comparan según la especificación RFC 7232 de Solicitudes Condicionales, en lugar de la antigua RFC 2616.
patch_response_headers() ya no agrega un encabezado Last-Modified. Según la RFC 7234 Section 4.2.2, este encabezado es inútil junto con otros encabezados de caché que proporcionan una fecha de expiración explícita, como Expires o Cache-Control. UpdateCacheMiddleware y add_never_cache_headers() llaman a patch_response_headers() y por lo tanto también están afectados por este cambio.
En las plantillas del administrador, <p class="help"> se reemplaza con un tag <div> para permitir incluir listas dentro de texto de ayuda.
ConditionalGetMiddleware ya no establece el encabezado Date ya que los servidores web lo establecen. También ya no establece el encabezado Content-Length ya que esto ahora se hace por CommonMiddleware.
Si tienes un middleware que modifica el contenido de una respuesta y aparece antes de CommonMiddleware en las configuraciones MIDDLEWARE o MIDDLEWARE_CLASSES, debes reordenar tus middlewares para que las respuestas no se modifiquen después de haberse establecido Content-Length, o tener el middleware que modifica la respuesta resetear el encabezado Content-Length.
get_model() y get_models() ahora levantan una AppRegistryNotReady si se llaman antes de que los modelos de todas las aplicaciones hayan sido cargados. Anteriormente solo requerían que los modelos de la aplicación objetivo estuvieran cargados y así podían devolver modelos sin que todos sus relaciones estuvieran configuradas. Si necesitas el comportamiento antiguo de get_model(), establece el argumento require_ready en False.
Se elimina la atributo BaseCommand.can_import_settings no utilizado.
Se elimina la función documentada django.utils.functional.lazy_property.
Para consistencia con solicitudes no multipart, MultiPartParser.parse() deja ahora request.POST inmutable. Si estás modificando ese QueryDict, debes copiarlo primero, por ejemplo request.POST.copy().
Se elimina el soporte para cx_Oracle < 5.2.
El soporte para IPython < 1.0 se elimina de la orden shell.
La firma de la API privada Widget.build_attrs() cambia desde extra_attrs=None, **kwargs a base_attrs, extra_attrs=None.
Los objetos como archivo (por ejemplo, StringIO y BytesIO) subidos a un ImageField utilizando el cliente de prueba ahora requieren un atributo name con un valor que pase la validación del validate_image_file_extension.
FileField ahora mueve en lugar de copiar el archivo recibido. Con las configuraciones de subida de archivos por defecto, los archivos más grandes que FILE_UPLOAD_MAX_MEMORY_SIZE tienen ahora los mismos permisos que los archivos temporales (a menudo 0o600) en lugar del umask del sistema (a menudo 0o6644). Establece la configuración FILE_UPLOAD_PERMISSIONS si necesitas el mismo permiso independientemente de la tamaño del archivo.
Usa django.urls.reverse() en su lugar. Por ejemplo:
from django.db import models
class MyModel(models.Model):
...
@models.permalink
def url(self):
return ("guitarist_detail", [self.slug])
become
from django.db import models
from django.urls import reverse
class MyModel(models.Model):
...
def url(self):
return reverse("guitarist_detail", args=[self.slug])
Las vistas basadas en funciones de contrib.auth login() y logout() están descontinuadas a favor de nuevas vistas basadas en clases: LoginView y LogoutView.
El parámetro de contexto no utilizado extra_context de contrib.auth.views.logout_then_login() está descontinuado.
Las vistas basadas en funciones de contrib.auth password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm() y password_reset_complete() están descontinuadas a favor de nuevas vistas basadas en clases PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView y PasswordResetCompleteView.
django.test.runner.setup_databases() se ha movido a django.test.utils.setup_databases(). La ubicación antigua está deprecada.
django.utils.translation.string_concat() está descontinuado en favor de django.utils.text.format_lazy(). string_concat(*strings) se puede reemplazar por format_lazy('{}' * len(strings), *strings).
Para el back-end de caché PyLibMCCache, pasar configuraciones de comportamiento de pylibmc como atributos de nivel superior de OPTIONS está descontinuado. Establezca las bajo una clave behaviors dentro de OPTIONS en su lugar.
El host parámetro de django.utils.http.is_safe_url() está descontinuado en favor del nuevo parámetro allowed_hosts.
Silenciando las excepciones lanzadas mientras se renderiza el template tag {% include %} es descontinuado ya que el comportamiento suele ser más confuso que útil. En Django 2.1, la excepción será lanzada.
DatabaseIntrospection.get_indexes() está descontinuado en favor de DatabaseIntrospection.get_constraints().
authenticate() ahora pasa un argumento request a la función authenticate() del backend de autenticación. El soporte para métodos que no aceptan request como el primer argumento posicional se eliminará en Django 2.1.
El parámetro USE_ETAGS está descontinuado en favor de ConditionalGetMiddleware que ahora agrega la cabecera ETag a las respuestas sin importar el valor del parámetro. CommonMiddleware y django.utils.cache.patch_response_headers() ya no establecerán ETags cuando termine la descontinuación.
Model._meta.has_auto_field está descontinuado en favor de comprobar si Model._meta.auto_field is not None.
Usar grupos de expresiones regulares con iLmsu# en url() está descontinuado. El único grupo útil es (?i) para URLs no sensibles a mayúsculas y minúsculas, sin embargo, las URLs no sensibles a mayúsculas y minúsculas no son una buena práctica ya que crean múltiples entradas en los motores de búsqueda. Una solución alternativa podría ser crear un handler404 que busca caracteres mayúsculos en la URL y redirige a una equivalente en minúsculas.
Se agrega el argumento renderer al método Widget.render(). Los métodos que no aceptan ese argumento seguirán funcionando durante un período de descontinuación.
may 31, 2026