Notas de lanzamiento de Django 1.5

26 de febrero de 2013

Bienvenidos a Django 1.5!

Estas notas de lanzamiento cubren las nuevas características, así como algunos cambios incompatibles con la retrocompatibilidad que querrás tener en cuenta al actualizar desde Django 1.4 o versiones anteriores. También hemos eliminado algunas características, que se detallan en nuestro plan de desprecación, y hemos comenzado el proceso de desprecación para algunas características <deprecated-features-1.5>>.

Resumen

La característica más grande nueva en Django 1.5 es el modelo de usuario configurable. Antes de Django 1.5, las aplicaciones que querían utilizar el marco de autenticación de Django (django.contrib.auth) estaban obligadas a usar la definición de Django de un «usuario». En Django 1.5, ahora puedes cambiar el modelo User por uno que tú mismo escribas. Esto podría ser una simple extensión del modelo User existente – por ejemplo, podrías agregar un campo ID de Twitter o Facebook – o podrías reemplazar completamente el modelo User con uno totalmente personalizado para tu sitio.

Django 1.5 también es la primera versión que incluye soporte para Python 3! Nosotros etiquetamos este soporte como «experimental» porque no consideramos aún que esté listo para producción, pero todo está en su lugar para que puedas empezar a portar tus aplicaciones a Python 3. Nuestra próxima versión, Django 1.6, apoyará Python 3 sin reservas.

Otras características nuevas destacadas en Django 1.5 incluyen:

Donde sea posible, intentamos introducir nuevas características de manera compatible con la versión anterior según nuestra política de estabilidad de API <misc/api-stability>. Sin embargo, como en versiones anteriores, Django 1.5 incluye algunas cambios incompatibles con la versión anterior; las personas que actualizan desde versiones anteriores de Django deben leer esa lista cuidadosamente.

Una característica obsoleta digna de mención es el cambio a «estilos nuevos» url etiqueta. Anteriormente a Django 1.3, sintaxis como {% url myview %} se interpretaba incorrectamente (Django consideraba "myview" como un nombre literal de una vista, no como una variable de plantilla llamada myview). Django 1.3 y versiones posteriores introdujeron la sintaxis {% load url from future %} para traer el comportamiento corregido donde myview se veía como una variable.

El resultado de esto es que si no estás utilizando {% load url from future %} en tus plantillas, necesitarás cambiar etiquetas como {% url myview %} a {% url "myview" %}. Si estabas utilizando {% load url from future %}, puedes simplemente eliminar esa línea bajo Django 1.5

Compatibilidad con Python

Django 1.5 requiere Python 2.6.5 o superior, aunque recomendamos fuertemente Python 2.7.3 o superior. El soporte para Python 2.5 y versiones anteriores ha sido eliminado.

Este cambio debería afectar solo a un pequeño número de usuarios de Django, ya que la mayoría de los proveedores de sistemas operativos hoy en día están enviando Python 2.6 o nuevo como su versión predeterminada. Si todavía estás utilizando Python 2.5, sin embargo, necesitarás seguir utilizando Django 1.4 hasta que puedas actualizar tu versión de Python. Según nuestra política de soporte, Django 1.4 continuará recibiendo soporte de seguridad hasta la publicación de Django 1.6.

Django 1.5 no se ejecuta en una liberación final de Jython, porque la última versión de Jython no admite actualmente Python 2.6. Sin embargo, Jython ofrece actualmente una versión alpha que incluye el soporte para 2.7 y Django 1.5 admite esa versión alpha.

Soporte de Python 3

Django 1.5 introduce el soporte para Python 3 - específicamente, Python 3.2 y superior. Esto se presenta en forma de un código base único; no es necesario instalar una versión diferente de Django en Python 3. Esto significa que puedes escribir aplicaciones destinadas a Python 2, Python 3 o aplicaciones singulares que soporten ambas plataformas.

Sin embargo, estamos etiquetando este soporte como «experimental» por ahora: aunque ha recibido una extensa prueba mediante nuestra suite de pruebas automatizadas, ha recibido muy poca prueba en el mundo real. Hemos hecho nuestro mejor esfuerzo para eliminar los bugs, pero no podemos estar seguros de que hemos cubierto todos los posibles usos de Django.

Algunas características de Django no están disponibles porque dependen del software de terceros que aún no ha sido portado a Python 3, incluyendo:

Además, Django es más que un framework web; es un ecosistema de componentes pluggables. En este punto, muy pocos aplicaciones de terceros han sido portadas a Python 3, por lo que es poco probable que una aplicación real tenga todas sus dependencias satisfechas bajo Python 3.

Por tanto, recomendamos no utilizar Django 1.5 en producción bajo Python 3. En su lugar, aprovecha esta oportunidad para comenzar a portar aplicaciones a Python 3. Si eres un autor de un componente pluggable, te animamos a empezar a portarlo ahora.

Tenemos planes para ofrecer soporte de primera clase y listo para producción para Python 3 en nuestra próxima versión, Django 1.6.

¿Qué hay de nuevo en Django 1.5

Modelo de usuario configurable

En Django 1.5, puedes utilizar tu propio modelo como almacenamiento para datos relacionados con el usuario. Si tu proyecto necesita un nombre de usuario con más de 30 caracteres, o si deseas almacenar los nombres del usuario en un formato diferente al nombre y apellido, o quieres agregar información de perfil personalizada a tu objeto User, ahora puedes hacerlo.

Si tienes una aplicación reutilizable de terceros que referencia el modelo de usuario, es posible que debas realizar algunos cambios en la forma en que se refieren las instancias de User. También deberías documentar cualquier característica específica del modelo de usuario que tu aplicación dependa.

Consulta la documentación sobre modelos de usuario personalizados para obtener más detalles.

Soporte para guardar un subconjunto de campos del modelo

La método Model.save() tiene un nuevo argumento de palabra clave update_fields. Al utilizar este argumento es posible guardar solo una lista selectiva de campos del modelo. Esto puede ser útil por razones de rendimiento o cuando se intenta evitar sobreescribir cambios concurrentes.

Las instancias diferidas (cargadas mediante .only() o .defer()) guardarán automáticamente solo los campos cargados. Si algún campo se establece manualmente después del carga, ese campo también se actualizará al guardar.

Consulta la Model.save() documentación para obtener más detalles.

Soporte explícito para respuestas en streaming

Antes de Django 1.5, era posible crear una respuesta en streaming pasando un iterador a HttpResponse. Pero esto era inconfiable: cualquier middleware que accediera al atributo content consumiría el iterador prematuramente.

Ahora puedes generar explícitamente una respuesta en streaming con la nueva clase de StreamingHttpResponse. Esta clase expone un atributo streaming_content que es un iterador.

Dado que StreamingHttpResponse no tiene un atributo content, cualquier middleware que necesite acceso al contenido de la respuesta debe probar si se trata de respuestas en streaming y comportarse según corresponda.

{% verbatim %} etiqueta de plantilla

Para hacer más fácil tratar con plantillas de JavaScript que colisionan con el sintaxis de Django, puedes ahora usar la verbatim bloque de etiqueta para evitar parsear el contenido de la etiqueta.

Recuperación de instancias ContentType asociadas a modelos proxy

Los métodos ContentTypeManager.get_for_model() y ContentTypeManager.get_for_models() tienen un nuevo argumento de palabra clave – respectivamente for_concrete_model y for_concrete_models. Al pasar False utilizando este argumento es posible recuperar la ContentType asociada a modelos proxy.

La traducción de los textos es la siguiente:

En todas las vistas basadas en clases genericas (vistas basadas en clases genericas o cualquier vista que herede de ContextMixin), el diccionario del contexto contiene una variable view que apunta a la instancia de la clase View.

GeoDjango

  • Los objetos LineString y MultiLineString GEOS ahora admiten los métodos interpolate() y project() (llamados de referencia lineal).

  • Las propiedades wkb y hex de los objetos GEOSGeometry preservan la dimensión Z.

  • Se ha agregado soporte para PostGIS 2.0 y se ha eliminado el soporte para GDAL < 1.5.

Nuevas tutoriales

Las adiciones a los documentos incluyen un tutorial 3 renovado (Tutorial 3) y un nuevo tutorial sobre la prueba. Una nueva sección, «Tutoriales avanzados», ofrece Cómo escribir aplicaciones reutilizables así como una guía paso a paso para nuevos contribuyentes en Escribiendo tu primer parche para Django.

Características menores

Django 1.5 también incluye varias mejoras más pequeñas dignas de mención:

  • El motor de plantillas ahora interpreta True, False y None como los objetos correspondientes de Python.

  • django.utils.timezone proporciona una ayuda para convertir fechas y horas conscientes entre zonas horarias. Consulte localtime().

  • Los textos traducidos son:

  • Las vistas generales admiten solicitudes OPTIONS.

    Además, cuando salgas errores o mensajes en tus comandos personalizados, debes utilizar ahora self.stdout.write('mensaje') y self.stderr.write('error') (consulte la nota sobre el salida de los comandos de administración).

  • La orden del comando de administración dumpdata produce una fila a la vez, evitando errores de memoria insuficiente al exportar conjuntos de datos grandes.

  • En el localflavor para Canadá, pq se agregó a los códigos aceptables para Quebec. Es una antigua abreviatura.

  • El decorador receiver ahora puede conectarse a más de un señal suministrando una lista de señales.

  • En la administración, puedes filtrar usuarios por grupos a los que pertenecen.

  • La función QuerySet.bulk_create() ahora tiene el argumento batch_size. Por defecto, el tamaño de lote no está limitado excepto para SQLite donde un solo lote está limitado para que no se excedan los 999 parámetros por consulta.

  • Las configuraciones LOGIN_URL y LOGIN_REDIRECT_URL ahora también aceptan nombres de funciones de vistas y patrones de URL nombrados. Esto permite reducir la duplicación de configuración. Puedes encontrar más información en la documentación del login_required().

  • Django ahora proporciona un manejador de autenticación para mod_wsgi: auth handler.

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

  • Se almacena una instancia de ResolverMatch en la solicitud como resolver_match.

  • Por defecto, todos los mensajes de registro que llegan a la logger django cuando DEBUG es True se envían a la consola (a menos que redefinas el logger en tu LOGGING configuración).

  • Al utilizar RequestContext, ahora es posible buscar permisos utilizando {% if 'someapp.someperm' in perms %} en plantillas.

  • Ya no se requiere tener las plantillas 404.html y 500.html en la carpeta raíz de las plantillas. Django mostrará algunos mensajes de error básicos para ambos casos cuando esas plantillas no están disponibles. Aún se recomienda proporcionar esas plantillas para presentar páginas de errores atractivas al usuario.

  • django.contrib.auth proporciona un nuevo señal que se emite cada vez que un usuario falla en iniciar sesión con éxito. Consulta user_login_failed.

  • La nueva opción loaddata --ignorenonexistent ignora los datos de los campos que ya no existen.

  • Los nuevos métodos de aserción assertXMLEqual() y assertXMLNotEqual() permiten probar la igualdad del contenido XML a nivel semántico, sin preocuparse por las diferencias en sintaxis (espacios, orden de atributos, etc.).

  • El middleware RemoteUserMiddleware ahora fuerza el cierre de sesión cuando el encabezado REMOTE_USER desaparece durante la misma sesión del navegador.

  • La backend de almacenamiento de sesiones basada en caché cache-based session backend puede almacenar los datos de sesión en un caché no por defecto.

  • Los textos traducidos son:

  • Durante la configuración de depuración de Django, las advertencias de Deprecación están habilitadas y las advertencias se capturan en el sistema de registro. Las advertencias registradas se dirigen a través del manipulador de registro console, que por defecto requiere que DEBUG sea True para generar salida. El resultado es que las DeprecationWarnings deberían imprimirse en la consola en entornos de desarrollo de la misma manera que lo han hecho las versiones de Python < 2.7.

  • La API del método django.contrib.admin.ModelAdmin.message_user() ha sido modificada para aceptar argumentos adicionales, añadiendo capacidades similares a django.contrib.messages.add_message(). Esto es útil para generar mensajes de error desde acciones administrativas.

  • Los filtros de lista del administrador pueden ahora ser personalizados por solicitud gracias al nuevo método django.contrib.admin.ModelAdmin.get_list_filter().

Cambios incompatibles con la versión anterior en 1.5

Advertencia

Además de los cambios descritos en esta sección, asegúrate de revisar el plan de desprecación 1.5 para cualquier característica que haya sido eliminada. Si no has actualizado tu código dentro del plazo de desprecación dado para una característica determinada, su eliminación puede aparecer como un cambio incompatibles con la versión anterior.

ALLOWED_HOSTS requerido en producción

El nuevo ALLOWED_HOSTS establece la validación del encabezado Host de la solicitud y protege contra ataques de host-poisoning. Este parámetro es ahora necesario siempre que DEBUG sea False, o de lo contrario django.http.HttpRequest.get_host() levantará una SuspiciousOperation. Para obtener más detalles, consulta la documentación completa del nuevo parámetro <ALLOWED_HOSTS>.

Administradores en modelos abstractos

Los modelos abstractos pueden definir un administrador personalizado y ese administrador será heredado por cualquier modelo concreto que extienda el modelo abstracto. Sin embargo, si intentas usar el modelo abstracto para llamar a un método en el administrador, se levantará una excepción. Anteriormente, la llamada habría sido permitida pero fallaría tan pronto como cualquier operación de base de datos fuera intentada (usualmente con un error «la tabla no existe» desde la base de datos).

Si tienes funcionalidad en un administrador que has estado invocando utilizando la clase abstracta, debes migrar esa lógica a una función estática o de clase staticmethod o classmethod en la clase abstracta.

Contexto en vistas basadas en clases para archivos de archivo de año

Para consistencia con las otras vistas genéricas basadas en fecha, YearArchiveView ahora pasa year en el contexto como un datetime.date en lugar de una cadena. Si estás utilizando {{ year }} en tus plantillas, debes reemplazarlo con {{ year|date:"Y" }}.

También se agregaron next_year y previous_year en el contexto. Se calculan según allow_empty y allow_future.

Contexto en vistas basadas en clases para archivos de archivo de año y mes

YearArchiveView y MonthArchiveView se documentaron para proporcionar una lista de fechas date_list ordenada en orden ascendente en el contexto, como sus predecesores basados en funciones, pero estaba en realidad en orden descendente. En 1.5, se restauró el orden documentado. Es posible que desees agregar (o eliminar) la palabra clave reversed cuando estés iterando sobre date_list en una plantilla:

{% for date in date_list reversed %}

ArchiveIndexView sigue proporcionando una lista de fechas date_list en orden descendente.

Contexto en TemplateView

Para consistencia con el diseño de las otras vistas genéricas, TemplateView ya no pasa un diccionario params en el contexto, en su lugar pasando directamente las variables del URLconf al contexto.

Datos no de formulario en solicitudes HTTP

request.POST ya no incluirá datos enviados mediante solicitudes HTTP con contenido específico de tipo no formularios en la cabecera. En versiones anteriores, los datos enviados con tipos de contenido distintos a multipart/form-data o application/x-www-form-urlencoded aún terminaban representados en el atributo request.POST. Los desarrolladores que deseen acceder al dato POST bruto para estos casos, deberían utilizar el atributo request.body en su lugar.

request_finished signal

Django enviaba el señal request_finished tan pronto como la función de vista devolvía una respuesta. Esto interactuaba mal con las respuestas de transmisión <httpresponse-streaming> que retrasan la generación del contenido.

Esta señal se envía ahora después de que el contenido ha sido consumido por completo por el gateway WSGI. Esto podría ser incompatible en sentido inverso si dependes de que la señal se dispare antes de enviar el contenido de respuesta al cliente. Si lo haces, deberías considerar utilizar middleware en su lugar.

Nota

Algunos servidores y middleware WSGI no siempre llaman a close en el objeto de respuesta después de manejar una solicitud, especialmente uWSGI anterior a 1.2.6 y el middleware de informes de errores de Sentry hasta 2.0.7. En esos casos la señal request_finished no se envía en absoluto. Esto puede dar lugar a conexiones inactivas con servidores de bases de datos y caché.

Solicitudes OPTIONS, PUT y DELETE en el cliente de prueba

A diferencia de GET y POST, estos métodos HTTP no están implementados por los navegadores web. En su lugar, se utilizan en APIs, que transfieren datos en formatos como JSON o XML. Dado que tales solicitudes pueden contener datos arbitrarios, Django no intenta descodificar su cuerpo.

Sin embargo, el cliente de prueba utilizaba a construir una cadena de consulta para las solicitudes OPTIONS y DELETE como si fueran GET, y un cuerpo de solicitud para las solicitudes PUT como si fueran POST. Esta codificación era arbitraria e inconsistente con el comportamiento de Django cuando recibe las solicitudes, por lo que se eliminó en Django 1.5.

Si estabas utilizando el parámetro data en una solicitud OPTIONS o DELETE, debes convertirlo a cadena de consulta y anexarlo al parámetro path.

Si estabas utilizando el parámetro data en una solicitud PUT sin especificar un tipo de contenido, debes codificar tus datos antes de pasarlos al cliente de prueba y establecer la argumento content_type.

La versión del sistema de simplejson ya no se utiliza

Se explica más abajo, Django 1.5 depura django.utils.simplejson en favor del módulo json incorporado de Python 2.6. En teoría, esta modificación es inofensiva. Desafortunadamente, debido a incompatibilidades entre versiones de simplejson, puede desencadenar errores en algunas circunstancias.

Las características relacionadas con JSON en Django 1.4 siempre utilizaron django.utils.simplejson. Este módulo era realmente:

  • Una versión del sistema de simplejson, si estaba disponible (es decir, import simplejson funciona), si era más reciente que la copia incorporada de Django o tenía las aceleraciones C, o

  • El módulo json de la biblioteca estándar, si estaba disponible (es decir, Python 2.6 o superior), o

  • Una copia incorporada de la versión 2.0.7 de simplejson.

En Django 1.5, esas características utilizan el módulo json de Python, que se basa en la versión 2.0.9 de simplejson.

No hay incompatibilidades conocidas entre la copia de Django de la versión 2.0.7 y la copia de Python de la versión 2.0.9. Sin embargo, hay algunas incompatibilidades entre otras versiones de simplejson:

  • Mientras que la API de simplejson está documentada como siempre devuelve cadenas Unicode, la implementación opcional C puede devolver una cadena de bytes. Esto se corrigió en Python 2.7.

  • simplejson.JSONEncoder obtuvo un argumento de palabra clave namedtuple_as_object en la versión 2.2.

More information on these incompatibilities is available in ticket #18023.

El resultado neto es que, si has instalado simplejson y tu código utiliza internamente la serialización de Django directamente – por ejemplo django.core.serializers.json.DjangoJSONEncoder, el cambio de simplejson a json podría romper tu código. (En general, los cambios en las internas no están documentados; estamos haciendo una excepción aquí.)

En este punto, los mantenedores de Django creen que utilizar json desde la biblioteca estándar ofrece la garantía más fuerte de compatibilidad hacia atrás. Recomiendan usarlo a partir de ahora.

Tipos de cadena de métodos del hashador

Si has escrito un hashador de contraseña personalizado, tus métodos encode(), verify() o safe_summary() deberían aceptar parámetros Unicode (password, salt o encoded). Si cualquier método de hashing necesita cadenas de bytes, puedes utilizar la utilidad force_bytes() para codificar las cadenas.

Validación de previous_page_number y next_page_number

Cuando se utiliza la paginación de objetos, los métodos previous_page_number() y next_page_number() del objeto Page no comprobaban si el número devuelto estaba dentro del rango de páginas existente. Lo hace ahora y lanza una excepción InvalidPage cuando el número es demasiado bajo o demasiado alto.

Cambios en la conducta de la opción autocommit de base de datos en PostgreSQL

La opción autocommit de PostgreSQL no funcionaba como se anunciaba anteriormente. Funcionaba para un bloque de transacción única, pero después del primer bloque nunca se restauraba el comportamiento de autocommit. Este bug está ahora arreglado en 1.5. Si bien esto es solo una corrección de bug, vale la pena comprobar el comportamiento de tus aplicaciones si estás utilizando PostgreSQL junto con la opción autocommit.

La sesión no se guarda en respuestas 500

La sesión middleware de Django omitirá la guarda del datos de sesión si el código de estado de respuesta es 500.

Verificación de correos en intento de inicio de sesión fallido

Antes de Django 1.5, si intentabas iniciar sesión en la interfaz administrativa y usabas por error tu dirección de correo electrónico en lugar de tu nombre de usuario, la interfaz administrativa mostraba un aviso advirtiendo que tu dirección de correo electrónico no era tu nombre de usuario. En Django 1.5, la introducción de los modelos de usuarios personalizados <auth-custom-user> ha requerido la eliminación de este aviso. Esto no cambia el comportamiento de inicio en el sitio administrativo; solo afecta al mensaje de advertencia que se muestra bajo un modo particular de falla de inicio de sesión.

Cambios en la ejecución de pruebas

Se han introducido algunas cambios en la ejecución de las pruebas que pueden ser incompatibles con algunos entornos de prueba:

Vaciar la base de datos en django.test.TransactionTestCase

Anteriormente, se truncaba la base de datos de prueba antes de cada ejecución de prueba en un TransactionTestCase.

Para poder ejecutar pruebas unitarias en cualquier orden y asegurarse de que siempre están aisladas entre sí, los TransactionTestCase ahora resetearán la base de datos después de cada ejecución de prueba en lugar de antes.

No más reinicio implícito de secuencias de BD

Los tests de TransactionTestCase usaban a renglón seguido a resetear las secuencias de clave primaria automáticamente junto con las acciones de vaciado de la base de datos descritas anteriormente.

No se resetean secuencias explícitamente. Esto puede causar que las pruebas TransactionTestCase que dependen de valores primarios hard-codificados rompan.

La nueva atributo reset_sequences se puede utilizar para forzar el comportamiento antiguo para TransactionTestCase que lo necesiten.

Ordenación de pruebas

Para asegurarse de que todo el código TestCase comienza con una base de datos limpia, las pruebas se ejecutan en el siguiente orden:

  • Primero, todos los tests unitarios (incluyendo unittest.TestCase, SimpleTestCase, TestCase y TransactionTestCase) se ejecutan sin ningún orden garantizado ni impuesto entre ellos.

  • Luego cualquier otra prueba (por ejemplo, doctests) que pueda alterar la base de datos sin restaurarla a su estado original se ejecuta.

Esto no debería causar problemas a menos que tengas pruebas existentes que asuman que una TransactionTestCase ejecutada anteriormente dejó algún estado de la base de datos detrás o tests unitarios que dependen de alguna forma de estado preservado después de la ejecución de otras pruebas. Tales pruebas ya son muy frágiles y deben cambiarse para poder ejecutarse de manera independiente.

Diccionario cleaned_data mantenido para formularios inválidos

El diccionario cleaned_data siempre está presente después de la validación del formulario. Cuando el formulario no se valida, contiene solo los campos que pasaron la validación. Debes probar el éxito de la validación con el método is_valid() y no con la presencia o ausencia del atributo cleaned_data en el formulario.

Comportamiento de syncdb con múltiples bases de datos

Ahora que syncdb consulta a los routers de la base de datos para determinar si se deben crear tipos de contenido (cuando contenttypes está habilitado) y permisos (cuando auth está habilitado) en la base de datos objetivo. Anteriormente, los creaba en la base de datos predeterminada, incluso cuando se especificaba otra base de datos con la opción --database.

Si utilizas syncdb en múltiples bases de datos, asegúrate de que tus routers permitan sincronizar tipos de contenido y permisos solo en una de ellas. Consulta los docs sobre el comportamiento de las aplicaciones contribuyentes con múltiples bases de datos <contrib_app_multiple_databases> para obtener más información.

El deserializador XML no parseará documentos que contengan un DTD

Para evitar la exposición a ataques de denegación de servicio relacionados con referencias de entidades externas y expansión de entidades, el deserializador de modelos XML ahora rechaza los documentos XML que contienen un DTD (definición del tipo de documento). Dado que el serializador XML no produce un DTD, esto no afectará el uso típico, solo casos en los que se pasan documentos XML personalizados a Django’s deserializador de modelos.

El valor por defecto de max_num para formsets

Un valor por defecto de None para la argumento max_num de una fábrica de formset ya no permite cualquier número de formularios en el conjunto de formularios. En su lugar, para prevenir ataques de agotamiento de memoria, ahora tiene un límite de 1000 formularios. Este límite se puede elevar estableciendo explícitamente un valor más alto para max_num.

Miscelánea

  • La clase django.forms.ModelMultipleChoiceField devuelve ahora una colección vacía como el valor vacío en lugar de una lista vacía.

  • La función int_to_base36() ahora lanza correctamente un error TypeError en lugar de un error ValueError para entradas no enteras.

  • El filtro de plantilla slugify está disponible como una función Python estándar en django.utils.text.slugify(). De manera similar, remove_tags está disponible en django.utils.html.remove_tags().

  • Los archivos subidos ya no se crean con permisos ejecutables por defecto. Si necesitas que sean ejecutables, cambia el valor de FILE_UPLOAD_PERMISSIONS a tus necesidades. El nuevo valor por defecto es 0o666 (octal) y el valor actual del máscara se elimina primero.

  • Los textos traducidos son:

  • En una llamada a filter(), cuando las expresiones F contenían consultas que abarcaban relaciones de múltiples valores, no siempre reutilizaban las mismas relaciones que otras consultas en la misma cadena. Esto se cambió y ahora las expresiones F() utilizarán siempre las mismas relaciones que otras consultas dentro del mismo llamado a filter().

  • El etiqueta de plantilla token csrf ya no está encerrada en un div. Si necesitas la validación HTML contra los DTDs pre-HTML5 estrictos, debes agregar un div alrededor de ella en tus páginas.

  • La biblioteca de etiquetas de plantilla adminmedia, que solo contenía la etiqueta de plantilla obsoleta {% admin_media_prefix %}, fue eliminada. Intentar cargarla con {% load adminmedia %} fallará. Si tus plantillas todavía contienen esa línea, debes eliminarla.

  • Debido a un error en la implementación, era posible utilizar django.contrib.redirects sin habilitar django.contrib.sites. Esto ya no está permitido. Si estás utilizando django.contrib.redirects, asegúrate de que INSTALLED_APPS contenga django.contrib.sites.

  • La función BoundField.label_tag ahora escapa su argumento contents. Para evitar la escapada HTML, utiliza django.utils.safestring.mark_safe() en el argumento antes de pasarla.

  • Acceder a las relaciones uno-a-uno reversas obtenidas mediante select_related() ahora lanza DoesNotExist en lugar de devolver None.

Características obsoletas en 1.5

django.contrib.localflavor

La aplicación contribuyente localflavor se ha dividido en paquetes separados. django.contrib.localflavor misma será eliminada en Django 1.6, después de una desactivación acelerada.

Los nuevos paquetes están disponibles en GitHub. El equipo central no puede mantener eficientemente estos paquetes a largo plazo — abarca solo una docena de países en este momento; similar a las traducciones, la mantenimiento se transferirá a los miembros interesados de la comunidad.

django.contrib.markup

El módulo contrib de markup ha sido descontinuado y seguirá un calendario de descontinuación acelerado. El uso directo de bibliotecas de marcado de Python o bibliotecas de etiquetas de terceros se prefiere a que Django mantenga esta funcionalidad en el marco.

AUTH_PROFILE_MODULE

Con la introducción de modelos de usuario personalizados <auth-custom-user>, ya no hay necesidad de un mecanismo integrado para almacenar datos de perfil de usuario.

Puedes definir aún modelos de perfiles de usuario que tengan una relación uno a uno con el modelo User - de hecho, para muchas aplicaciones que necesitan asociar datos con una cuenta de usuario, este será un patrón de diseño apropiado para seguir. Sin embargo, la configuración AUTH_PROFILE_MODULE y el método django.contrib.auth.models.User.get_profile() para acceder al modelo de perfil de usuario ya no deben usarse.

El comportamiento de streaming de HttpResponse

Django 1.5 descontinúa la capacidad de streamear una respuesta pasando un iterador a HttpResponse. Si dependes de este comportamiento, cambia a StreamingHttpResponse. Consulta Soporte explícito para respuestas en streaming arriba.

En Django 1.7 y superior, el iterador se consumirá inmediatamente por HttpResponse.

django.utils.simplejson

Desde Django 1.5, se ha dejado de apoyar Python 2.5, por lo que ahora podemos confiar en que el módulo json esté disponible en la biblioteca estándar de Python, por lo que hemos eliminado nuestra propia copia de simplejson. Debes importar ahora json en lugar de django.utils.simplejson.

Desafortunadamente, esta modificación puede tener efectos secundarios no deseados debido a incompatibilidades entre versiones de simplejson – véase la sección de cambios incompatibles <simplejson-incompatibilities> . Si dependes de características agregadas a simplejson después de que se convirtió en Python’s json, debes importar simplejson explícitamente.

django.utils.encoding.StrAndUnicode

La mezcla django.utils.encoding.StrAndUnicode ha sido deprecada. Define un método __str__ y aplica el decorador django.utils.encoding.python_2_unicode_compatible en su lugar.

django.utils.itercompat.product

La función django.utils.itercompat.product ha sido deprecada. Utiliza la función incorporada itertools.product() en su lugar.

Comando de administración cleanup

El comando de administración cleanup ha sido deprecado y reemplazado por clearsessions.

Script daily_cleanup.py

El script no documentado daily_cleanup.py ha sido deprecado. Utiliza el comando de administración clearsessions en su lugar.