Notas de lanzamiento de Django 1.7

2 de septiembre de 2014

Bienvenido a Django 1.7!

Estas notas de lanzamiento cubren las nuevas características, así como algunas cambios incompatibles con la retrocompatibilidad que desecharás estar al tanto cuando actualices Django 1.6 o versiones anteriores. Hemos comenzado el proceso de desactivación para algunas características <deprecated-features-1.7>`, y algunas características han alcanzado el final de su proceso de desactivación y han sido eliminadas.

Compatibilidad con Python

Django 1.7 requiere Python 2.7, 3.2, 3.3 o 3.4. Recomendamos y solo oficialmente apoyamos la última versión de cada serie.

La serie Django 1.6 es la última que soporta Python 2.6. Django 1.7 es la primera versión que soporta Python 3.4.

Esta modificación 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.7 o una versión más nueva como su versión predeterminada. Si todavía estás utilizando Python 2.6, sin embargo, necesitarás seguir utilizando Django 1.6 hasta que puedas actualizar tu versión de Python. Según nuestra política de soporte <internals/release-process>, Django 1.6 continuará recibiendo soporte de seguridad hasta la publicación de Django 1.8.

Qué hay de nuevo en Django 1.7

Migraciones de esquema

Django ahora tiene un soporte integrado para migraciones de esquema. Permite actualizar, cambiar y eliminar modelos creando archivos de migración que representen los cambios del modelo y que pueden ejecutarse en cualquier base de datos de desarrollo, staging o producción.

Las migraciones se cubren en la documentación propia <topics/migrations>, pero algunos de los características clave son:

  • syncdb ha sido deprecado y reemplazado por migrate. No te preocupes - las llamadas a syncdb seguirán funcionando como antes.

  • El comando nuevo makemigrations proporciona una forma fácil de autodetectar cambios en tus modelos y hacer migraciones para ellos.

    django.db.models.signals.pre_syncdb y django.db.models.signals.post_syncdb han sido deprecados, para ser reemplazados por pre_migrate y post_migrate respectivamente. Estos nuevos señales tienen argumentos ligeramente diferentes. Revisa la documentación para obtener más detalles.

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

  • Los fijos initial_data ya no se cargan para aplicaciones con migraciones; si quieres cargar datos iniciales para una aplicación, te sugerimos crear una migración para tu aplicación y definir una operación RunPython o RunSQL en la sección operations de la migración.

  • El comportamiento del rollback de pruebas es diferente para aplicaciones con migraciones; en particular, Django ya no emulará los rollbacks en bases de datos no transaccionales o dentro de Rollback emulation a menos que se solicite específicamente.

  • No se recomienda tener aplicaciones sin migraciones dependientes (con una ForeignKey o ManyToManyField hacia) aplicaciones con migraciones.

Refactorización de carga de aplicaciones

Históricamente, las aplicaciones Django estaban estrechamente vinculadas a modelos. Un singleton conocido como el «cache de la aplicación» se ocupaba tanto de las aplicaciones instaladas como de los modelos. El módulo de modelos se utilizaba como identificador para las aplicaciones en muchas APIs.

A medida que maduró el concepto de aplicaciones Django, este código mostró algunas debilidades. Ha sido refactorizado en un «registro de aplicaciones» donde los módulos de modelos ya no tienen un papel central y donde es posible adjuntar datos de configuración a las aplicaciones.

Las mejoras realizadas hasta ahora incluyen:

  • Las aplicaciones pueden ejecutar código al inicio, antes de que Django haga cualquier otra cosa, con el método ready() de su configuración.

  • Los etiquetas de las aplicaciones se asignan correctamente a los modelos incluso cuando están definidos fuera de models.py. Ya no tienes que establecer explícitamente la etiqueta de aplicación en app_label.

  • Es posible omitir models.py en su totalidad si una aplicación no tiene modelos.

  • Las aplicaciones pueden ser reetiquetadas con la label de las configuraciones de aplicación para trabajar alrededor de conflictos de etiquetas.

  • El nombre de las aplicaciones se puede personalizar en la administración con el verbose_name de configuraciones de aplicaciones.

  • El administrador llama automáticamente a autodiscover() cuando se inicia Django. Puedes eliminar consecuentemente esta línea de tu URLconf.

  • Django importa todas las configuraciones de aplicaciones y modelos tan pronto como inicia, mediante un proceso determinista y directo. Esto debería hacer que sea más fácil diagnosticar problemas de importación, tales como bucles de importación.

Nueva función en las subclases de Campo

Ahora la clase Field tiene un nuevo método requerido llamado deconstruct() para ayudar a realizar las migraciones de esquema y facilitar la adición de claves compuestas en futuras versiones de Django.

Este método no toma argumentos y devuelve una tupla de cuatro elementos:

  • name: El nombre de la atributo del campo en su modelo padre, o None si no forma parte de un modelo.

  • path: Una ruta de Python puntuada al clase de este campo, incluyendo el nombre de la clase.

  • args: Argumentos posicionales, como una lista

  • kwargs: Argumentos clave, como un diccionario

Estas cuatro variables permiten que cualquier campo se serialice en un archivo, así como permitir que el campo se copie de manera segura, ambas partes esenciales de estas nuevas características.

Esta modificación no debería afectarte a menos que escribas subclases personalizadas de campos; si lo haces, puede que necesites reimplementar el método deconstruct() si tu subclase cambia la firma del método __init__ de cualquier manera. Si tu campo solo hereda de un campo integrado de Django y no sobreescribe __init__, no son necesarias cambios.

Si necesitas sobreescribir deconstruct(), una buena forma de empezar es con los campos integrados de Django (django/db/models/fields/__init__.py) ya que varios campos, incluyendo DecimalField y DateField, lo sobreescriben y muestran cómo llamar al método en la superclase y simplemente agregar o eliminar argumentos adicionales.

Esto también significa que todos los argumentos de los campos deben ser ellos mismos serializables; para ver qué consideramos serializable, y encontrar cómo hacer que tus propias clases sean serializables, lee la documentación sobre serialización de migraciones: migration serialization documentation.

Llamando métodos personalizados QuerySet desde el Manager

Históricamente, la forma recomendada de hacer consultas modelo reutilizables era crear métodos en una clase Manager personalizada. El problema con este enfoque fue que después del primer llamado a un método, se devolvía una instancia QuerySet y no se podían llamar métodos adicionales del manager personalizado.

Aunque no estaba documentado, era común trabajar alrededor de este problema creando un QuerySet personalizado para que los métodos personalizados pudieran ser encadenados; pero la solución tenía varios inconvenientes:

  • El QuerySet y sus métodos personalizados se perdían después del primer llamado a values() o values_list().

  • Los textos traducidos son:

La QuerySet.as_manager() clase de método puede ahora devolver directamente un Manager con métodos de QuerySet:

class FoodQuerySet(models.QuerySet):
    def pizzas(self):
        return self.filter(kind="pizza")

    def vegetarian(self):
        return self.filter(vegetarian=True)


class Food(models.Model):
    kind = models.CharField(max_length=50)
    vegetarian = models.BooleanField(default=False)
    objects = FoodQuerySet.as_manager()


Food.objects.pizzas().vegetarian()

Usar un manager personalizado al recorrer relaciones reversas

Es posible ahora especificar un manager personalizado cuando se recorre una relación reversible:

class Blog(models.Model):
    pass


class Entry(models.Model):
    blog = models.ForeignKey(Blog)

    objects = models.Manager()  # Default Manager
    entries = EntryManager()  # Custom Manager


b = Blog.objects.get(id=1)
b.entry_set(manager="entries").all()

Nueva framework de comprobaciones del sistema

Hemos agregado una nueva framework de comprobaciones del sistema para detectar problemas comunes (como modelos inválidos) y proporcionar pistas para resolver esos problemas. El framework es extensible, por lo que puedes agregar tus propias comprobaciones para tus propios apps y bibliotecas.

Para realizar comprobaciones del sistema, se utiliza el comando de administración check. Este comando reemplaza al antiguo comando de administración validate.

Admin shortcuts soportan zonas horarias

Los atajos «hoy» y «ahora» junto a los campos de fecha y hora en la interfaz administrativa ahora funcionan según la hora actual. Anteriormente, utilizaban la zona horaria del navegador, lo que podía dar lugar a guardar el valor incorrecto cuando no coincidía con la zona horaria actual del servidor.

Además, los widgets ahora muestran un mensaje de ayuda cuando la zona horaria del navegador y del servidor son diferentes, para aclarar cómo se interpretará el valor insertado en el campo.

Usando cursor de base de datos como administradores de contexto

Antes de Python 2.7, los cursor de base de datos podían usarse como administradores de contexto. El comportamiento del administrador de contexto estaba definido por el cursor específico del backend. Se cambió el comportamiento de las consultas de método mágico con Python 2.7 y ya no se podían usar los cursor como administradores de contexto.

Django 1.7 permite que un cursor se use como administrador de contexto. Es decir, lo siguiente puede usarse:

with connection.cursor() as c:
    c.execute(...)

en lugar de:

c = connection.cursor()
try:
    c.execute(...)
finally:
    c.close()

Búsquedas personalizadas

Ahora es posible escribir búsquedas y transformaciones personalizadas para el ORM. Las búsquedas personalizadas funcionan exactamente igual que las búsquedas integradas de Django (por ejemplo, lte, icontains) mientras que las transformaciones son un nuevo concepto.

La traducción de los textos es la siguiente:

La clase django.db.models.Transform permite transformaciones de valores de base de datos antes del último lookup. Por ejemplo, es posible escribir una transformación year que extrae el año del valor del campo. Las transformaciones permiten la cadena de procesos. Después de haber agregado la transformación year a DateField, se puede filtrar en el valor transformado, por ejemplo qs.filter(author__birthdate__year__lte=1981).

Para obtener más información sobre tanto lookups personalizados como transformaciones, consulte la documentación de lookups personalizados.

Mejoras en el manejo de errores de Form

Form.add_error()

Hasta ahora había dos patrones principales para manejar errores en formularios:

  • Elevando una ValidationError desde dentro de ciertas funciones (por ejemplo, Field.clean(), Form.clean_<fieldname>() o Form.clean() para errores no relacionados con campos).

  • Manipulando Form._errors cuando se está dirigiendo a un campo específico en Form.clean() o agregando errores desde fuera de un método «limpio» (por ejemplo, directamente desde una vista).

El uso del primer patrón era sencillo ya que el formulario puede adivinar desde el contexto (es decir, qué método levantó la excepción) dónde pertenecen los errores y procesarlos automáticamente. Esto sigue siendo la forma canónica de agregar errores cuando sea posible. Sin embargo, el segundo era farragoso y propenso a errores, ya que la carga de manejar casos de borde recayó en el usuario.

El nuevo método add_error() permite agregar errores a campos de formulario específicos desde cualquier lugar sin tener que preocuparse por los detalles como crear instancias de django.forms.utils.ErrorList o tratar con Form.cleaned_data. Esta nueva API reemplaza la manipulación de Form._errors, que ahora se convierte en una API privada.

See validando-campos-con-clean para un ejemplo utilizando Form.add_error().

Metadata de errores

El constructor ValidationError acepta metadata como el código de error code o los parámetros params, que luego están disponibles para interpolar en la mensaje de error (consulte levantando-error-de-validación para obtener más detalles); sin embargo, antes de Django 1.7 se descartaban esas metadatos tan pronto como los errores se agregaban a Form.errors.

Form.errors y django.forms.utils.ErrorList ahora almacenan las instancias de ValidationError para que puedas recuperar esas metadatos en cualquier momento mediante el nuevo método Form.errors.as_data.

Las instancias de ValidationError recuperadas luego se pueden identificar gracias a su código de error, lo que permite cosas como reescribir el mensaje del error o escribir lógica personalizada en una vista cuando un error específico esté presente. También se puede utilizar para serializar los errores en un formato personalizado como XML.

El nuevo método Form.errors.as_json() es un método de conveniencia que devuelve mensajes de error junto con códigos de error serializados como JSON. as_json() utiliza as_data() y da una idea de cómo podría extenderse el nuevo sistema.

Contenedores de errores y compatibilidad hacia atrás

Fueron necesarias cambios pesados en los varios contenedores de errores para apoyar las características mencionadas anteriormente, específicamente Form.errors, django.forms.utils.ErrorList y las almacenaciones internas de ValidationError. Estos contenedores que antes almacenaban cadenas de error ahora almacenan instancias de ValidationError y se han adaptado las APIs públicas para hacer esto lo más transparente posible, pero si has estado utilizando APIs privadas, algunas de las modificaciones son incompatibles con la versión anterior; consulte constructor-de-error-de-validación-y-almacenamiento-interno para obtener más detalles.

Características menores

django.contrib.admin

  • Puedes implementar ahora los atributos site_header, site_title y index_title en un sitio administrativo personalizado AdminSite para cambiar fácilmente el título de la página y el texto del encabezado del sitio administrativo. ¡Ya no necesitas sobreescribir plantillas!

  • Los botones en django.contrib.admin ahora utilizan la propiedad CSS border-radius para esquinas redondeadas en lugar de imágenes GIF de fondo.

  • Algunas plantillas de administración ahora tienen clases app-<app_name> y model-<model_name> en su etiqueta <body> para permitir la personalización del CSS por aplicación o modelo.

  • Las celdas de la lista de cambios de la administración ahora tienen una clase field-<field_name> en el HTML para habilitar las personalizaciones de estilo.

  • Los campos de búsqueda de la administración pueden ahora ser personalizados por solicitud gracias al nuevo método django.contrib.admin.ModelAdmin.get_search_fields().

  • El método ModelAdmin.get_fields() puede sobrescribirse para personalizar el valor de ModelAdmin.fields.

  • Además del sintaxis existente admin.site.register, puedes utilizar el nuevo decorador register() para registrar una ModelAdmin.

  • Puedes especificar ModelAdmin.list_display_links = None para deshabilitar los enlaces en la página de lista de cambios.

  • Puedes ahora especificar ModelAdmin.view_on_site para controlar si se muestra o no el enlace «Ver en sitio».

  • Puedes especificar un orden descendente para un valor de ModelAdmin.list_display prefixando el valor admin_order_field con un guión.

  • El método ModelAdmin.get_changeform_initial_data() puede sobrescribirse para definir comportamiento personalizado para establecer datos iniciales del formulario de cambio.

django.contrib.auth

django.contrib.formtools

  • Las llamadas a WizardView.done() ahora incluyen un form_dict para permitir el acceso más fácil a las formas por su nombre de paso.

django.contrib.gis

  • La versión predeterminada del biblioteca OpenLayers incluida en los widgets se ha actualizado desde 2.11 hasta 2.13.

  • Las geometrías preparadas ahora también admiten los predicados crosses, disjoint, overlaps, touches y within, si GEOS 3.3 o posterior está instalado.

django.contrib.messages

:modulo:`django.contrib.redirects`

django.contrib.sesiones

  • El backend de sesión "django.contrib.sessions.backends.cached_db" ahora respeta la configuración SESSION_CACHE_ALIAS. En versiones anteriores, siempre utilizaba el cache por defecto.

:modulo:`django.contrib.sitemaps`

django.contrib.sitios

django.contrib.archivos_estáticos

  • Las clases de almacenamiento de archivos estáticos <staticfiles-storages> pueden heredar para sobreescribir las permisos que los archivos y directorios estáticos reciban configurando los parámetros file_permissions_mode y directory_permissions_mode. Consulte la sección de ejemplo en collectstatic.

  • El backend CachedStaticFilesStorage obtiene una clase hermana llamada ManifestStaticFilesStorage que no utiliza el sistema de caché en absoluto, sino un archivo JSON llamado staticfiles.json para almacenar la relación entre el nombre del archivo original (por ejemplo, css/styles.css) y el nombre hashado del archivo (por ejemplo, css/styles.55e7cbb9ba48.css). El archivo staticfiles.json se crea cuando se ejecuta el comando de administración collectstatic y debería ser una alternativa menos costosa para almacenamientos remotos como Amazon S3.

    Veamos las traducciones:

  • findstatic ahora acepta la bandera de verbosidad nivel 2, lo que significa que mostrará los caminos relativos de los directorios que ha buscado. Consulte findstatic para ver el ejemplo de salida.

django.contrib.syndication

  • El elemento updated de la fuente de syndication Atom1Feed ahora utiliza updateddate en lugar de pubdate, lo que permite incluir el elemento published en la fuente (que depende de pubdate).

Cache

  • Ahora se puede acceder a las cachés configuradas en CACHES mediante django.core.cache.caches. Este objeto similar a un diccionario proporciona una instancia diferente por hilo. Supersede django.core.cache.get_cache() que ahora está deprecado.

  • Si instancias los backends de caché directamente, ten en cuenta que ya no son thread-safe, ya que django.core.cache.caches ahora devuelve diferentes instancias por hilo.

  • Definir el argumento TIMEOUT del parámetro CACHES como None establecerá las claves de caché como «no expirables» por defecto. Anteriormente, solo era posible pasar timeout=None al método set() del backend de caché.

Cross Site Request Forgery

  • La configuración CSRF_COOKIE_AGE facilita el uso de cookies CSRF basadas en sesión.

Correo electrónico

  • send_mail() ahora acepta un parámetro html_message para enviar un correo electrónico multipartido con los tipos de contenido text/plain y text/html.

  • El SMTP EmailBackend ahora acepta un parámetro timeout.

Almacenamiento de archivos

  • La bloqueo de archivos en Windows dependía anteriormente del paquete PyWin32; si no estaba instalado, el bloqueo de archivos fallaba silenciosamente. Esa dependencia ha sido eliminada y el bloqueo de archivos se implementa ahora nativamente tanto en Windows como en Unix.

Subidas de archivo

  • El nuevo atributo UploadedFile.content_type_extra contiene parámetros adicionales pasados al encabezado content-type durante una subida de archivo.

  • El nuevo ajuste FILE_UPLOAD_DIRECTORY_PERMISSIONS controla las permisos del sistema de archivos de los directorios creados durante la subida de archivo, como lo hace el ajuste FILE_UPLOAD_PERMISSIONS para los archivos mismos.

  • El atributo FileField.upload_to ya no es obligatorio. Si se omite o se da None o una cadena vacía, no se utilizará un subdirectorio para almacenar los archivos subidos.

  • Los archivos subidos se cierran explícitamente antes de que la respuesta sea entregada al cliente. Los archivos subidos parcialmente también se cierran siempre y cuando tengan el nombre file en el manipulador de carga.

  • La función Storage.get_available_name() ahora agrega un guión bajo más una cadena alfanumérica aleatoria de 7 caracteres (por ejemplo, "_x3a1gho"), en lugar de iterar a través de un guión bajo seguido de un número (por ejemplo, "_1", "_2", etc.) para prevenir un ataque de denegación de servicio. Esta modificación también se hizo en las liberaciones de seguridad 1.6.6, 1.5.9 y 1.4.14.

Formularios

  • Los etiquetas <label> y <input> renderizados por RadioSelect y CheckboxSelectMultiple al recorrer los botones de radio o las casillas de verificación incluyen ahora atributos for y id, respectivamente. Cada botón de radio o casilla de verificación incluye un atributo id_for_label para producir el ID del elemento.

  • Las etiquetas <textarea> renderizadas por Textarea ahora incluyen un atributo maxlength si el campo de modelo TextField tiene una max_length.

  • Campo.choices ahora permite personalizar la etiqueta de «opción vacía» incluyendo una tupla con una cadena vacía o None como clave y el texto personalizado como valor. La opción vacía por defecto "----------" se omitirá en este caso.

  • MultiValueField permite campos opcionales estableciendo la argumento require_all_fields a False. El atributo required para cada campo individual se respetará, y se levantará un nuevo error de validación incomplete cuando cualquier campo requerido esté vacío.

  • La clean() método en una forma ya no necesita devolver self.cleaned_data. Si devuelve un diccionario modificado, ese será utilizado aún así.

  • Después de una regresión temporal en Django 1.6, ahora es posible nuevamente hacer que el método coerce de TypedChoiceField devuelva un valor arbitrario.

  • SelectDateWidget.months se puede utilizar para personalizar la palabra de los meses mostrados en el widget select.

  • Se agregaron los parámetros min_num y validate_min a formset_factory() para permitir validar un número mínimo de formularios enviados.

  • Las metaclasses utilizadas por Form y ModelForm se rehicieron para apoyar más escenarios de herencia. La limitación previa que impedía heredar tanto de Form como de ModelForm al mismo tiempo ha sido removida siempre que ModelForm aparezca primero en el MRO.

  • Ahora es posible eliminar un campo de una Form cuando se subclase estableciendo el nombre a None.

  • Ahora es posible personalizar los mensajes de error para las restricciones unique, unique_for_date y unique_together de ModelForm. Para apoyar unique_together o cualquier otro NON_FIELD_ERROR, ModelForm ahora busca la clave NON_FIELD_ERROR en el diccionario error_messages del Meta interno de la ModelForm. Consulte consideraciones sobre error_messages del modelo para más detalles.

Internacionalización

  • La django.middleware.locale.LocaleMiddleware.response_redirect_class atributo permite personalizar los redireccionamientos emitidos por el middleware.

  • Los LocaleMiddleware ahora almacena el idioma seleccionado por el usuario con la clave de sesión _language. Solo debe ser accedido utilizando la constante LANGUAGE_SESSION_KEY. Anteriormente se almacenaba con la clave django_language y no existía la constante LANGUAGE_SESSION_KEY, pero las claves reservadas para Django deben comenzar con un guión bajo. Para compatibilidad hacia atrás, todavía se lee de django_language en 1.7. Las sesiones se migrarán a la nueva clave mientras se escriben.

  • El blocktrans ahora admite una opción trimmed. Esta opción eliminará los caracteres de línea de fin y comienzo del contenido del tag {% blocktrans %}, reemplazará cualquier espacio en blanco al principio o final de una línea y fusionará todas las líneas en una sola utilizando un carácter de espacio para separarlas. Esto es muy útil para indentar el contenido del tag {% blocktrans %} sin que los caracteres de indentación terminen en la correspondiente entrada en el archivo .po, lo que facilita el proceso de traducción.

  • Cuando ejecutes makemessages desde la carpeta raíz de tu proyecto, cualquier cadena extraída ahora se distribuirá automáticamente a la ficha de mensajes del proyecto o aplicación correspondiente. Consulta Localización: cómo crear archivos de idiomas para obtener más detalles.

  • El comando makemessages ahora siempre agrega el flag de línea de comandos --previous al comando msgmerge, manteniendo las cadenas traducidas previamente en los archivos .po para las cadenas difusas.

  • Se introdujeron las siguientes configuraciones para ajustar las opciones del cookie de idioma: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_DOMAIN y LANGUAGE_COOKIE_PATH.

  • Se agregó Format localization para el idioma Esperanto.

Comandos de Gestión

  • La nueva opción --no-color del comando django-admin deshabilita la colorización de la salida de los comandos de gestión.

  • Las nuevas opciones dumpdata --natural-foreign y dumpdata --natural-primary, así como las nuevas argumentos use_natural_foreign_keys y use_natural_primary_keys para el método serializers.serialize(), permiten utilizar claves primarias naturales al serializar.

  • Ya no es necesario proporcionar el nombre de la tabla de caché o la opción --database para el comando createcachetable. Django obtiene esta información del archivo de configuración. Si has configurado múltiples caches o bases de datos, se crean todas las tablas de caché.

  • El comando runserver recibió varias mejoras:

    • Los textos traducidos son:

    • Además, el servidor de desarrollo se recarga automáticamente cuando se actualiza un archivo de traducción, es decir, después de ejecutar compilemessages.

    • Todos los pedidos HTTP se registran en la consola, incluyendo peticiones para archivos estáticos o favicon.ico que antes se filtraban.

  • Los comandos administrativos pueden producir ahora salida coloreada de sintaxis bajo Windows si el herramienta ANSICON de terceros está instalada y activa.

  • El comando collectstatic con opción de enlace simbólico ahora se admite en Windows NT 6 (Windows Vista y posterior).

  • Los datos SQL iniciales funcionan mejor si está instalado el paquete Python sqlparse.

    Ten en cuenta que está desaconsejado a favor de la operación RunSQL de las migraciones, que se benefician del comportamiento mejorado.

Modelos

  • Se agregó el método QuerySet.update_or_create().

  • La nueva opción Meta del modelo default_permissions permite personalizar (o deshabilitar) la creación de los permisos por defecto de agregar, cambiar y eliminar.

  • Los campos OneToOneField explícitos para la herencia múltiple de tablas ahora se descubren en las clases abstractas.

  • Ahora es posible evitar crear una relación hacia atrás para OneToOneField estableciendo su related_name a '+' o finalizándolo con '+'.

  • Las expresiones <django.db.models.F> admiten el operador de potencia (**).

  • Los métodos remove() y clear() de los administradores relacionados creados por ForeignKey y GenericForeignKey ahora aceptan la argumento clave bulk para controlar si se deben realizar las operaciones en bloque (es decir, utilizando QuerySet.update()). Por defecto es True.

  • Ahora es posible utilizar None como valor de consulta para el lookup iexact.

  • Ahora es posible pasar una función llamable como valor para la atributo limit_choices_to cuando se define un ForeignKey o ManyToManyField.

  • Llamar a only() y defer() en el resultado de QuerySet.values() ahora lanza un error (antes, esto provocaba un error de base de datos o datos incorrectos).

  • Puedes utilizar una sola lista para index_together (en lugar de una lista de listas) cuando se especifica un conjunto único de campos.

  • Los modelos intermedios personalizados que tienen más de un campo foráneo con cualquier modelo participante en una relación muchos-a-muchos ahora están permitidos, siempre y cuando especifiques explícitamente los campos foráneos a utilizar estableciendo el nuevo argumento ManyToManyField.through_fields.

  • Asignar una instancia de modelo a un campo no relacionado ahora lanzará un error. Anteriormente esto funcionaba si el campo aceptaba enteros como entrada ya que tomaba la clave primaria.

  • Los campos enteros ahora se validan contra los valores mínimo y máximo específicos del backend de base de datos basados en su internal_type. Anteriormente la validación de campo de modelo no impedía que se guardaran valores fuera del rango asociado al tipo de dato de columna, lo que provocaba un error de integridad.

  • Ahora es posible ordenar explícitamente un campo de relación _id por su nombre de atributo utilizando su nombre de atributo.

Señales

  • Se agregó el argumento enter al señal setting_changed.

  • Los señales de modelos pueden conectarse ahora usando una cadena str del forma 'app_label.ModelName' – exactamente como los campos relacionados – para referenciar de manera perezosa a sus emisores.

Plantillas

  • El método Context.push() ahora devuelve un administrador de contexto que llama automáticamente a pop() al salir del bloque with. Además, push() acepta parámetros que se pasan al constructor dict utilizado para construir el nuevo nivel de contexto.

  • El nuevo método Context.flatten() devuelve la pila de un objeto Context como un diccionario plano.

  • Los objetos Context pueden compararse ahora por igualdad (internamente, esto utiliza el método Context.flatten(), por lo que la estructura interna de cada pila de Context no importa siempre y cuando sus versiones planas sean idénticas).

  • El etiqueta de plantilla widthratio ahora acepta un parámetro "as" para capturar el resultado en una variable.

  • La etiqueta de plantilla include ahora también aceptará cualquier cosa con un método render() (como una Template) como argumento. Los argumentos de cadena se buscarán utilizando la función get_template() tal como siempre.

  • Ahora es posible incluir plantillas de manera recursiva.

  • Los objetos de plantilla ahora tienen un atributo origen establecido cuando TEMPLATE_DEBUG es True. Esto permite inspeccionar y registrar las fuentes de las plantillas fuera de la infraestructura django.template.

  • Las excepciones TypeError ya no se silencian cuando se lanzan durante la renderización de un template.

  • Las siguientes funciones ahora aceptan el parámetro dirs que es una lista o tupla para sobreescribir TEMPLATE_DIRS:

  • El filtro time ahora acepta especificadores de formato relacionados con la zona horaria 'e', 'O' , 'T' y 'Z' y es capaz de digerir instancias de datetime conscientes de la zona horaria realizando la renderización esperada.

  • El etiqueta cache ahora intentará utilizar el cache llamado «template_fragments» si existe y caerá en el uso del cache por defecto en caso contrario. También acepta un argumento using opcional para controlar qué cache utiliza.

  • El nuevo filtro truncatechars_html truncará una cadena a no ser más larga que el número de caracteres especificado, teniendo en cuenta el HTML.

Solicitudes y respuestas

  • La nueva atributo HttpRequest.scheme especifica el esquema de la solicitud (http o https normalmente).

  • El atajo redirect() ahora admite URLs relativas.

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

Pruebas

  • DiscoverRunner tiene dos nuevos atributos, test_suite y test_runner, que facilitan la sobrescritura de la forma en que se recopilan y ejecutan las pruebas.

  • Se agregó el argumento fetch_redirect_response a assertRedirects(). Dado que el cliente de prueba no puede obtener URLs externas, esto permite utilizar assertRedirects con redirecciones que no forman parte de tu aplicación Django.

  • Se corrige el manejo del esquema al realizar comparaciones en assertRedirects().

  • Se agregó el argumento secure a todos los métodos de solicitud de la clase Client. Si True, la solicitud se hará a través de HTTPS.

  • assertNumQueries() ahora imprime la lista de consultas ejecutadas si falla la afirmación.

  • La instancia de WSGIRequest generada por el manipulador de pruebas se adjunta ahora al atributo django.test.Response.wsgi_request.

  • Se han recopilado las configuraciones de base de datos para la prueba en un diccionario llamado TEST.

Utilidades

  • Se ha mejorado la precisión de strip_tags(), aunque todavía no puede garantizar un resultado seguro para HTML, como se indica en la documentación.

Validadores

  • RegexValidator ahora acepta los argumentos opcionales flags y booleano inverse_match. El atributo inverse_match determina si se debe levantar el error de validación ValidationError cuando el patrón de expresión regular coincide (True) o no coincide (False, por defecto) con el valor proporcionado. El atributo flags establece las banderas utilizadas al compilar una cadena de expresión regular.

  • URLValidator ahora acepta un argumento opcional schemes que permite la personalización de los esquemas URI admitidos (en lugar de los por defecto http(s) y ftp(s)).

  • validate_email() ahora admite direcciones con literales IPv6, como example@[2001:db8::1], tal como se especifica en RFC 5321.

Cambios incompatibles con la versión anterior en 1.7

Advertencia

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

allow_syncdb / allow_migrate

Aunque Django seguirá buscando métodos allow_syncdb, aunque deberían haber sido renombrados a allow_migrate, hay una diferencia sutil en los modelos que se pasan a estos métodos.

Para aplicaciones con migraciones, allow_migrate ahora recibirá modelos históricos, que son modelos versionados especiales sin atributos personalizados, métodos ni administradores. Asegúrese de que sus métodos allow_migrate solo se refieran a campos o otros elementos en model._meta.

initial_data

Las aplicaciones con migraciones no cargarán los fijos de datos iniciales cuando hayan terminado de migrar. Las aplicaciones sin migraciones seguirán cargando estos fijos durante la fase de migrate que emula el comportamiento antiguo de syncdb, pero cualquier nueva aplicación no tendrá esta funcionalidad.

En su lugar, se le anima a cargar datos iniciales en las migraciones si es necesario (utilizando la operación RunPython y sus clases de modelo); esto tiene el beneficio adicional de que sus datos iniciales no necesitarán actualizarse cada vez que cambie el esquema.

Además, como el resto del código antiguo de Django syncdb, initial_data ha sido iniciado en la ruta de desaparición y será eliminado en Django 1.9.

deconstruct() y serializabilidad

Django requiere ahora que todas las clases Field y todos sus argumentos de constructor sean serializables. Si modificas la firma del constructor en tu clase Field personalizada de alguna manera, necesitarás implementar un método deconstruct(); hemos ampliado la documentación de la clase Field personalizada con instrucciones para implementar este método.

La exigencia de que todos los argumentos de campo sean serializables significa que cualquier instancia de clase personalizada que se esté pasando a los constructores de Field - cosas como clases Storage personalizadas, por ejemplo - necesitan tener un método deconstruct definido en ellos también, aunque Django proporciona una decoradora de clase útil que funcionará para la mayoría de las aplicaciones.

Cambios en el cargado de aplicaciones

Secuencia de inicio

Django 1.7 carga configuraciones y modelos de aplicaciones tan pronto como comienza a ejecutarse. Si bien este comportamiento es más directo y se cree que es más robusto, no se pueden descartar regresiones. Consulte aplicaciones-troubleshooting para soluciones a algunos problemas que podrías encontrar.

Scripts independientes

Si estás utilizando Django en un script de Python puro —en lugar de una orden de comando— y dependes del variable de entorno DJANGO_SETTINGS_MODULE, debes inicializar explícitamente a Django al principio de tu script con:

>>> import django
>>> django.setup()

De lo contrario, golpearás una excepción AppRegistryNotReady.

WSGI scripts

Hasta Django 1.3, la forma recomendada de crear una aplicación WSGI era:

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

En Django 1.4, se mejoró el soporte para WSGI y se cambió la API a:

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

Si todavía estás utilizando el estilo anterior en tu script WSGI, necesitarás actualizarlo al último o te saldrá una excepción AppRegistryNotReady.

Consistencia del registro de aplicaciones

Ya no es posible tener varias aplicaciones instaladas con el mismo etiqueta. En versiones anteriores de Django, esto no siempre funcionaba correctamente, pero tampoco provocaba un error directo.

Si tienes dos apps con la misma etiqueta, deberías crear una AppConfig para una de ellas y sobreescribir su label allí. Luego debes ajustar tu código en todos los lugares donde se refiera a esta aplicación o sus modelos con la antigua etiqueta.

Ya no es posible importar el mismo modelo dos veces a través de diferentes rutas. A partir de Django 1.6, esto solo puede suceder si manualmente colocas un directorio y una subdirectorio en PYTHONPATH. Consulta la sección sobre la nueva estructura del proyecto en las notas de lanzamiento de la versión 1.4 <https://docs.djangoproject.com/es/1.4/releases/1.4-notes/> para obtener instrucciones de migración.

Debes asegurarte de que:

  • Todos los modelos están definidos en aplicaciones que se enumeran en INSTALLED_APPS o tienen una etiqueta explícita app_label.

  • Los modelos no se importan como efecto secundario de cargar su aplicación. Específicamente, no debes importar modelos en el módulo raíz de una aplicación ni en el módulo que define su clase de configuración.

Django aplicará estas requisitos a partir de la versión 1.9, después de un período de desactivación.

Herencia de AppCommand

Las clases hijas de AppCommand deben implementar ahora el método handle_app_config() en lugar de handle_app(). Este método recibe una instancia de AppConfig en lugar de un módulo de modelos.

Introspección de aplicaciones

Dado que INSTALLED_APPS ahora admite clases de configuración de aplicación además de módulos de aplicación, debes revisar el código que accede directamente a este ajuste y utilizar el registro de aplicaciones (django.apps.apps) en su lugar.

El registro de aplicaciones ha preservado algunas características del antiguo caché de aplicaciones. Aunque el caché de aplicaciones era una API privada, se eliminarán métodos y argumentos obsoletos a través de un camino de desactivación estándar, con la excepción de los siguientes cambios que tendrán efecto inmediato:

  • get_model lanza LookupError en lugar de devolver None cuando no se encuentra ningún modelo.

  • La argumento only_installed de get_model y get_models ya no existe, ni tampoco el argumento seed_cache de get_model.

Comandos de gestión y orden de INSTALLED_APPS

When several applications provide management commands with the same name, Django loads the command from the application that comes first in INSTALLED_APPS. Previous versions loaded the command from the application that came last.

Esto pone a la par la descubierta de comandos de administración con otras partes de Django que dependen del orden de INSTALLED_APPS, como archivos estáticos, plantillas y traducciones.

ValidationError constructor and internal storage

El comportamiento del constructor ValidationError ha cambiado cuando recibe un contenedor de errores como argumento (por ejemplo, una list o un ErrorList):

  • Convierte cualquier cadena que encuentre a instancias de ValidationError antes de agregarlas al almacenamiento interno.

  • No almacena el contenedor dado sino que copia su contenido al propio almacenamiento interno; anteriormente se agregaba el contenedor mismo a la instancia ValidationError y se utilizaba como almacenamiento interno.

Esto significa que si accedes a los almacenamientos internos de ValidationError, como error_list; error_dict o el valor de retorno de update_error_dict(), podrías encontrar instancias de ValidationError donde antes encontrabas cadenas.

También, si asignabas directamente el valor de retorno de update_error_dict() a Form._errors, podrías agregar inadvertidamente listas donde se esperan instancias de ErrorList. Esto es un problema porque una simple lista no sabe cómo manejar instancias de ValidationError.

La mayoría de los casos de uso que justificaban el uso de estas APIs privadas ahora están cubiertos por el método recién introducido Form.add_error():

# Old pattern:
try:
    ...
except ValidationError as e:
    self._errors = e.update_error_dict(self._errors)

# New pattern:
try:
    ...
except ValidationError as e:
    self.add_error(None, e)

Si necesitas compatibilidad con Django <= 1.6 y 1.7, no puedes usar Form.add_error() ya que no estaba disponible antes de Django 1.7, pero puedes utilizar el siguiente trabajo alrededor para convertir cualquier list en ErrorList:

try:
    ...
except ValidationError as e:
    self._errors = e.update_error_dict(self._errors)

# Additional code to ensure ``ErrorDict`` is exclusively
# composed of ``ErrorList`` instances.
for field, error_list in self._errors.items():
    if not isinstance(error_list, self.error_class):
        self._errors[field] = self.error_class(error_list)

El comportamiento de LocMemCache frente a errores de pickle

Una inconsistencia existía en versiones anteriores de Django respecto a cómo se manejan los errores de pickle por diferentes backends de caché. django.core.cache.backends.locmem.LocMemCache solía fallar silenciosamente cuando ocurría tal error, lo cual es inconsistente con otros backends y lleva a errores específicos del caché. Esto ha sido corregido en Django 1.7, consulte #21200 para más detalles.

Las claves de caché se generan ahora desde la URL absoluta de la solicitud

Versiones anteriores de Django generaban claves de caché utilizando el camino y la cadena de consulta de una solicitud, pero no el esquema ni el host. Si una aplicación de Django estaba sirviendo múltiples subdominios o dominios, las claves de caché podían colisionar. En Django 1.7, las claves de caché varían por la URL absoluta de la solicitud incluyendo esquema, host, camino y cadena de consulta. Por ejemplo, la parte de URL de una clave de caché se genera ahora desde https://www.example.com/path/to/?key=val en lugar de /path/to/?key=val. Las claves de caché generadas por Django 1.7 serán diferentes a las generadas por versiones anteriores de Django. Después de actualizar a Django 1.7, la primera solicitud a cualquier URL previamente cacheada será un error de caché.

Pasando None a Manager.db_manager()

En versiones anteriores de Django, era posible utilizar db_manager(using=None) en una instancia del administrador de modelos para obtener una instancia del administrador utilizando el comportamiento de routing por defecto, sobreescribiendo cualquier ruta de base de datos manualmente especificada. En Django 1.7, un valor de None pasado a db_manager producirá un router que retiene cualquier ruta de base de datos asignada manualmente – el administrador no será reseteado. Esto era necesario para resolver una inconsistencia en la forma en que se propagaba la información de routing sobre las uniones. Consulte #13724 para más detalles.

Puede ser requerido pytz

Si su proyecto maneja fechas y horas antes de 1970 o después de 2037 y Django lanza un error ValueError al encontrarlas, tendrá que instalar pytz. Es posible que esté afectado por este problema si utiliza formatos de fecha relacionados con la zona horaria de Django o el módulo django.contrib.syndication.

Estrategia de redirección del inicio de sesión administrativo

Históricamente, el sitio administrativo de Django pasaba la solicitud de un usuario no autorizado o no autenticado directamente a la vista de inicio de sesión, sin redirección HTTP. En Django 1.7, este comportamiento cambió para conformarse con una secuencia de trabajo más tradicional donde cualquier solicitud no autorizada a una página administrativa se redirige (con el código de estado HTTP 302) a la página de inicio de sesión, con el parámetro next configurado en el camino refiriendo. El usuario será redirigido allí después de un inicio de sesión exitoso.

También ten en cuenta que se ha actualizado el formulario de inicio de sesión administrativo para no contener el campo this_is_the_login_form (ahora sin uso) y el código ValidationError se ha establecido en la clave más regular invalid_login.

select_for_update() requiere una transacción

Históricamente, las consultas que utilizan select_for_update() podían ejecutarse en modo autocommit, fuera de una transacción. Antes de Django 1.6, el modo automático de transacciones de Django permitía esto para bloquear registros hasta la próxima operación de escritura. Desde que Django 1.6 introdujo el autocommit a nivel de base de datos, ejecutarlo en tal contexto anula el efecto de select_for_update(). Por lo tanto, ahora se asume que es un error y levanta una excepción.

Este cambio se hizo porque tales errores pueden ser causados por incluir una aplicación que espera transacciones globales (por ejemplo, ATOMIC_REQUESTS configurado en True), o el comportamiento de autocommit antiguo de Django, en un proyecto que no las ejecuta; y además, tales errores pueden manifestarse como bugs de corrupción de datos. También se hizo en Django 1.6.3.

Este cambio puede causar fallos de prueba si utilizas select_for_update() en una clase de pruebas que es una subclase de TransactionTestCase en lugar de TestCase.

Contrib middleware eliminado de MIDDLEWARE_CLASSES predeterminados

El refactor del cargado de aplicaciones desaconsejó utilizar modelos de aplicaciones que no son parte de la configuración INSTALLED_APPS. Esto expuso una incompatibilidad entre los valores predeterminados de INSTALLED_APPS y MIDDLEWARE_CLASSES en las configuraciones globales (django.conf.global_settings). Para llevar estas configuraciones alineadas y evitar advertencias de desactualización cuando se hacen cosas como probar aplicaciones reutilizables con configuraciones mínimas, SessionMiddleware, AuthenticationMiddleware y MessageMiddleware fueron eliminados de los valores predeterminados. Estas clases seguirán incluidas en las configuraciones generadas por defecto por startproject. La mayoría de los proyectos no serán afectados por este cambio, pero si no declarabas previamente MIDDLEWARE_CLASSES en tus configuraciones de proyecto y confiabas en el valor predeterminado global, asegúrate de que los nuevos valores predeterminados se alinean con las necesidades de tu proyecto. También debes verificar cualquier código que acceda a django.conf.global_settings.MIDDLEWARE_CLASSES directamente.

Miscelánea

  • El texto traducido es el siguiente:

  • ModelFormSets ya no eliminan instancias cuando se llama a save(commit=False). Consulta la can_delete para obtener instrucciones sobre cómo eliminar manualmente objetos de las formas eliminadas.

  • Cargar fijos vacíos emite una RuntimeWarning en lugar de levantar un CommandError.

  • django.contrib.staticfiles.views.serve() ahora levantará un Http404 excepción en lugar de un ImproperlyConfigured cuando DEBUG es False. Esta modificación elimina la necesidad de condicionar la adición del vista a tu root URLconf, lo que a su vez hace que sea seguro revertir por nombre. También elimina la capacidad para los visitantes de generar errores HTTP 500 spurius solicitando archivos estáticos que no existen o aún no se han recopilado.

  • El método django.db.models.Model.__eq__() ahora está definido de manera que las instancias de un modelo proxy y su modelo base sean consideradas iguales cuando coincidan los valores primarios. Anteriormente, solo las instancias del mismo clase eran consideradas iguales en la coincidencia de clave primaria.

  • El método django.db.models.Model.__eq__() ha cambiado de manera que dos instancias Model sin valores de clave primaria no serán consideradas iguales (a menos que sean la misma instancia).

  • El método django.db.models.Model.__hash__() ahora levantará una TypeError cuando se llame a un instancia sin valor de clave primaria. Esto se hace para evitar valores mutables __hash__ en contenedores.

  • Las columnas AutoField en bases de datos SQLite ahora se crearán utilizando la opción AUTOINCREMENT, que garantiza incrementos monotónicos. Esto causará un cambio en el comportamiento de numeración de claves primarias en SQLite, convirtiéndolo consistente con la mayoría de las otras bases de datos SQL. Esto solo se aplicará a tablas recién creadas. Si tienes una base de datos creada con una versión anterior de Django, necesitarás migrarla para aprovechar esta característica. Por ejemplo, podrías hacer lo siguiente:

    1. Utiliza dumpdata para guardar tus datos.

    2. Renombra el archivo de la base de datos existente (consérvelo como un respaldo).

    3. Ejecuta migrate para crear el esquema actualizado.

    4. Utiliza loaddata para importar los fixtures que exportaste en (1).

  • django.contrib.auth.models.AbstractUser ya no define un método get_absolute_url() . La definición antigua devolvía "/users/%s/" % urlquote(self.username) , lo cual era arbitrario ya que las aplicaciones pueden o no definir tal URL en urlpatterns. Define el método get_absolute_url() en tu propio objeto de usuario personalizado o utiliza ABSOLUTE_URL_OVERRIDES si deseas una URL para tu usuario.

  • La funcionalidad de servicio de activos estáticos de la clase django.test.LiveServerTestCase se ha simplificado: Ahora solo puede servir contenido ya presente en STATIC_ROOT cuando se ejecutan las pruebas. La capacidad de servir transparentemente todos los activos estáticos (de manera similar a lo que se obtiene con DEBUG = True durante el tiempo de desarrollo) ha sido movida a una nueva clase que vive en la aplicación staticfiles (la que realmente se encarga de tal función): django.contrib.staticfiles.testing.StaticLiveServerTestCase. En otras palabras, LiveServerTestCase misma es menos poderosa pero al mismo tiempo tiene menos magia.

    La razón detrás de esta acción es la eliminación de la dependencia del código no contribuido en aplicaciones contribuidas.

  • El antiguo sintaxis URI de caché (por ejemplo, "locmem://") ya no está soportado. Aún funcionaba, aunque no estaba documentado ni oficialmente soportado. Si todavía lo estás utilizando, por favor actualiza a la sintaxis CACHES actual.

  • El ordenamiento predeterminado de los campos Form en caso de herencia ha cambiado para seguir el MRO normal de Python. Los campos ahora se descubren al iterar a través del MRO en sentido inverso con la clase más alta que viene último. Esto solo afecta si has confiado en el ordenamiento predeterminado de los campos mientras tenías campos definidos tanto en la clase actual como en una Form padre.

  • El argumento required de SelectDateWidget ha sido eliminado. Este widget ahora respeta la propiedad is_required del campo formulario como otros widgets.

  • Widget.is_hidden ya no es una propiedad editable, obteniendo su valor al introspeccionar la presencia de input_type == 'hidden'.

  • select_related() ahora se combina de la misma manera que otras llamadas similares como prefetch_related. Es decir, select_related('foo', 'bar') es equivalente a select_related('foo').select_related('bar'). Anteriormente el último sería equivalente a select_related('bar').

  • GeoDjango dejó de soportar GEOS < 3.1.

  • La método init_connection_state de los backends de bases de datos ahora se ejecuta en modo autocomit (a menos que establezcas AUTOCOMMIT a False). Si mantienes un backend de base de datos personalizado, debes comprobar ese método.

  • La atributo allows_primary_key_0 de django.db.backends.BaseDatabaseFeatures se ha renombrado a allows_auto_pk_0 para describirlo mejor. Es True para todos los backends de base de datos incluidos con Django excepto MySQL, que permite claves primarias con valor 0. Solo prohíbe claves primarias autoincrementales con valor 0.

  • Se ha prohibido la sobrecarga de campos definidos en un modelo padre, ya que esto crea ambigüedad en el comportamiento del modelo esperado. Además, los campos conflictivos en la jerarquía de herencia de modelos resultan en un error de sistema de comprobación. Por ejemplo, si utilizas herencia múltiple, debes definir campos primarios personalizados en modelos padre, de lo contrario los campos id predeterminados colisionarán. Consulta La herencia múltiple para obtener más detalles.

  • django.utils.translation.parse_accept_lang_header() ahora devuelve locales minúsculas, en lugar del caso como se proporcionó originalmente. Como los locales deben tratarse de manera case-insensitive, esto nos permite acelerar la detección de locales.

  • django.utils.translation.get_language_from_path() y django.utils.translation.trans_real.get_supported_language_variant() ya no tienen un argumento supported.

  • La vista shortcut en django.contrib.contenttypes.views ahora admite URLs relativas al protocolo (por ejemplo, //example.com).

  • GenericRelation ahora admite un argumento related_query_name opcional. Establecer related_query_name agrega una relación desde el objeto relacionado hacia el tipo de contenido para la filtración, ordenación y otras operaciones de consulta.

  • Al ejecutar pruebas en PostgreSQL, el USER necesitará acceso de lectura a la base de datos incorporada postgres. Esto es en lugar del comportamiento anterior de conectarse a la base de datos no de prueba real.

  • Como parte del framework de comprobación de sistema, fields, models, and model managers implementan un método check() que se registra con el framework de comprobación. Si tienes un método existente llamado check() en uno de estos objetos, necesitarás renombrarlo.

  • Los textos traducidos son:

  • Los comandos de gestión sql* ahora respetan el método allow_migrate() del parámetro DATABASE_ROUTERS. Si tienes modelos sincronizados con bases de datos no por defecto, utiliza la bandera --database para obtener SQL para esos modelos (antes siempre se incluían en la salida).

  • La decodificación de la cadena de consulta desde URLs ahora cae hacia atrás a la codificación ISO-8859-1 cuando el input no es válido UTF-8.

  • Con la adición del django.contrib.auth.middleware.SessionAuthenticationMiddleware al plantilla de proyecto por defecto (solo pre-1.7.2), debe crearse una base de datos antes de acceder a una página utilizando runserver.

  • La adición del argumento schemes a URLValidator aparecerá como un cambio incompatible hacia atrás si estabas utilizando una expresión regular personalizada para validar esquemas. Cualquier esquema no listado en schemes fallará la validación, incluso si la expresión regular coincide con la URL dada.

Características deprecadas en 1.7

django.core.cache.get_cache

django.core.cache.get_cache ha sido sustituida por django.core.cache.caches.

django.utils.dictconfig/django.utils.importlib

django.utils.dictconfig y django.utils.importlib fueron copias de respectivamente logging.config y importlib proporcionadas para versiones de Python anteriores a 2.7. Han sido deprecados.

django.utils.module_loading.import_by_path

La función actual django.utils.module_loading.import_by_path captura excepciones AttributeError, ImportError y ValueError, y re-lanza la excepción ImproperlyConfigured. Esta ocultación de excepciones hace que sea innecesariamente difícil diagnosticar problemas de importación circular, porque hace que parezca que el problema proviene desde dentro de Django. Ha sido deprecada en favor de import_string().

django.utils.tzinfo

django.utils.tzinfo proporcionó dos subclases de tzinfo, LocalTimezone y FixedOffset. Han sido deprecadas en favor de alternativas más correctas proporcionadas por django.utils.timezone, django.utils.timezone.get_default_timezone() y django.utils.timezone.get_fixed_timezone().

django.utils.unittest

django.utils.unittest proporcionó acceso uniforme a la biblioteca unittest2 en todas las versiones de Python. Dado que unittest2 se convirtió en el módulo estándar unittest del lenguaje en Python 2.7, y Django 1.7 deja de apoyar versiones antiguas de Python, este módulo ya no es útil. Ha sido deprecado. Utiliza unittest en su lugar.

django.utils.datastructures.SortedDict

Como OrderedDict se agregó a la biblioteca estándar en Python 2.7, SortedDict ya no es necesario y ha sido deprecado.

Las dos métodos adicionales deprecados proporcionados por SortedDict (insert() y value_for_index()) han sido eliminados. Si dependías de estos métodos para alterar estructuras como campos de formulario, ahora debes tratar a estas OrderedDict como objetos inmutables y sobreescribirlos para cambiar su contenido.

Por ejemplo, podrías querer sobrescribir MyFormClass.base_fields (aunque este atributo no se considera una API pública) para cambiar el orden de los campos para todas las instancias de MyFormClass; o de manera similar, podrías sobreescribir self.fields desde dentro de MyFormClass.__init__(), para cambiar los campos para una instancia de formulario en particular. Por ejemplo (desde Django mismo):

PasswordChangeForm.base_fields = OrderedDict(
    (k, PasswordChangeForm.base_fields[k])
    for k in ["old_password", "new_password1", "new_password2"]
)

Custom SQL location for models package

Anteriormente, si los modelos estaban organizados en un paquete (myapp/models/) en lugar de simplemente myapp/models.py, Django buscaba inicialmente datos SQL en myapp/models/sql/. Este bug se ha corregido para que Django busque myapp/sql/ tal como está documentado. Después de que este problema fue resuelto, se agregaron migraciones que deprecaban los datos SQL iniciales. Por lo tanto, si bien esta modificación todavía existe, la deprecación es irrelevante ya que toda la función será eliminada en Django 1.9.

Reorganization of django.contrib.sites

django.contrib.sites proporciona funcionalidad reducida cuando no está en INSTALLED_APPS. La refactorización de carga de aplicaciones agrega algunas restricciones en esa situación. Como consecuencia, dos objetos se han movido y las ubicaciones anteriores están deprecadas:

declared_fieldsets attribute on ModelAdmin

La propiedad ModelAdmin.declared_fieldsets ha sido deprecada. A pesar de ser una API privada, seguirá un camino regular de deprecación. Esta propiedad se utilizaba principalmente por métodos que bypassaban ModelAdmin.get_fieldsets() pero esto se consideró un bug y se abordó.

Reorganization of django.contrib.contenttypes

Dado que django.contrib.contenttypes.generic definía tanto objetos de administración como relacionados con modelos, una importación de este módulo podría desencadenar efectos laterales inesperados. Como consecuencia, se dividieron sus contenidos en submódulos de contenttypes y el módulo django.contrib.contenttypes.generic está deprecado:

syncdb

El comando syncdb ha sido deprecado a favor del nuevo comando migrate. El comando migrate acepta los mismos argumentos que syncdb utilizaba, más algunos adicionales, por lo que es seguro cambiar solo el nombre con el que se llama y nada más.

Los módulos util renombrados a utils

Las siguientes instancias de util.py en la base de código de Django han sido renombradas a utils.py en un esfuerzo por unificar todas las referencias a util y utils:

  • django.contrib.admin.util

  • django.contrib.gis.db.backends.util

  • django.db.backends.util

  • django.forms.util

La función get_formsets en ModelAdmin

La función ModelAdmin.get_formsets ha sido deprecada a favor de la nueva get_formsets_with_inlines(), con el fin de manejar mejor el caso de mostrar inlines selectivamente en un ModelAdmin.

IPDirecciónDeRedField

Los campos django.db.models.IPAddressField y django.forms.IPAddressField han sido deprecados a favor de django.db.models.GenericIPAddressField y django.forms.GenericIPAddressField.

La función BaseMemcachedCache._get_memcache_timeout

La función privada BaseMemcachedCache._get_memcache_timeout() ha sido renombrada a get_backend_timeout(). A pesar de ser una API privada, seguirá con el proceso normal de deprecación.

Opciones de serialización de claves naturales

Las opciones --natural y -n para dumpdata han sido deprecadas. Utiliza en su lugar la opción dumpdata --natural-foreign.

De manera similar, el argumento use_natural_keys para serializers.serialize() ha sido deprecado. Utiliza en su lugar use_natural_foreign_keys.

Fusión de los argumentos POST y GET en WSGIRequest.REQUEST

Los textos traducidos son:

django.utils.datastructures.MergeDict class

MergeDict existe principalmente para apoyar la fusión de argumentos POST y GET en una propiedad REQUEST en WSGIRequest. Para fusionar diccionarios, utilice dict.update() en su lugar. La clase MergeDict está descontinuada y será eliminada en Django 1.9.

Códigos de idioma zh-cn, zh-tw y fy-nl

Los códigos de idioma utilizados actualmente para chino simplificado zh-cn, chino tradicional zh-tw y (frisio occidental) fy-nl están descontinuados y deben reemplazarse por los códigos de idioma zh-hans, zh-hant y fy respectivamente. Si utiliza estos códigos de idioma, debe renombrar los directorios de locale y actualizar sus configuraciones para reflejar estos cambios. Los códigos de idioma descontinuados serán eliminados en Django 1.9.

django.utils.functional.memoize function

La función memoize está descontinuada y debe reemplazarse por el decorador functools.lru_cache (disponible a partir de Python 3.2 en adelante).

Django incluye una versión backportada de este decorador para versiones antiguas de Python y está disponible en django.utils.lru_cache.lru_cache. La función descontinuada será eliminada en Django 1.9.

Geo Sitemaps

Google ha retirado el soporte para el formato Geo Sitemaps. Por lo tanto, el soporte de Django para Geo Sitemaps está descontinuado y será eliminado en Django 1.8.

Los textos traducidos son:

Argumentos llamables para consultas de conjunto fueron una característica no documentada que era inestable. Ha sido descontinuada y se eliminará en Django 1.9.

Los argumentos llamables se evaluaban cuando se construía un conjunto de consulta, en lugar de cuando se evaluaba, por lo tanto esta característica no ofrecía ningún beneficio comparado con evaluar los argumentos antes de pasarlos a la consulta y creó confusión sobre si los argumentos habían sido evaluados en tiempo de consulta.

Configuración ADMIN_FOR

La característica ADMIN_FOR, parte de admindocs, ha sido eliminada. Puedes eliminar la configuración de tu configuración con comodidad.

SplitDateTimeWidget con DateTimeField

El soporte de SplitDateTimeWidget en DateTimeField está descontinuado, utiliza SplitDateTimeWidget con SplitDateTimeField en su lugar.

validate

La orden de comando validate está descontinuada a favor del comando check.

django.core.management.BaseCommand

La traducción de los textos es la siguiente:

La método check() ha reemplazado al antiguo método validate().

Validadores de ModelAdmin

Las propiedades ModelAdmin.validator_class y default_validator_class están descontinuadas en favor de la nueva propiedad checks_class.

El método ModelAdmin.validate() está descontinuado en favor del método ModelAdmin.check().

El módulo django.contrib.admin.validation está descontinuado.

django.db.backends.DatabaseValidation.validate_field

Este método está descontinuado en favor de un nuevo método check_field. La funcionalidad requerida por check_field() es la misma que la proporcionada por validate_field(), pero el formato de salida es diferente. Los backends de bases de datos terceros que necesiten esta funcionalidad deben proporcionar una implementación del método check_field().

Cargar etiquetas de plantilla ssi y url desde la biblioteca future

Django 1.3 introdujo el sintaxis {% load ssi from future %} y {% load url from future %} para compatibilidad hacia adelante de las etiquetas de plantilla ssi y url. Esta sintaxis está descontinuada y se eliminará en Django 1.9. Puedes simplemente eliminar las etiquetas {% load ... from future %}.

django.utils.text.javascript_quote

javascript_quote() era una función no documentada presente en django.utils.text. Se utilizaba internamente en la vista javascript_catalog() cuya implementación se cambió para hacer uso de json.dumps() en su lugar. Si estabas confiando en esta función para proporcionar salida segura desde cadenas no fiables, debes utilizar django.utils.html.escapejs o el filtro de plantilla escapejs. Si todo lo que necesitas es generar cadenas de JavaScript válidas, puedes simplemente usar json.dumps().

Método y filtro de utilidad fix_ampersands

El método django.utils.html.fix_ampersands y el filtro de plantilla fix_ampersands están descontinuados, ya que la escapada de ampersandes se está tomando en cuenta por las características de escape HTML estándar de Django. Combinando esto con fix_ampersands resultaría en doble escape o, si el resultado se asume seguro, un riesgo de introducir vulnerabilidades XSS. Junto con fix_ampersands, también está descontinuado django.utils.html.clean_html, una función no documentada que llama a fix_ampersands. Dado que esta es una descontinuación acelerada, fix_ampersands y clean_html serán eliminados en Django 1.8.

Reorganización de configuraciones de pruebas de base de datos

Todas las configuraciones de base de datos con un prefijo TEST_ han sido descontinuadas a favor de entradas en un diccionario TEST en la configuración de la base de datos. Las configuraciones antiguas seguirán siendo soportadas hasta Django 1.9. Para compatibilidad con versiones anteriores de Django, puedes definir ambas versiones de las configuraciones siempre y cuando coincidan.

Soporte para FastCGI

El soporte para FastCGI a través del comando de gestión runfcgi será eliminado en Django 1.9. Por favor, despliega tu proyecto utilizando WSGI.

Objetos movidos en contrib.sites

Siguiendo la refactorización de carga de aplicaciones, dos objetos en django.contrib.sites.models debían ser movidos porque deben estar disponibles sin importar django.contrib.sites.models cuando django.contrib.sites no está instalado. Importa RequestSite desde django.contrib.sites.requests y get_current_site() de django.contrib.sites.shortcuts. Las ubicaciones de importación antiguas seguirán funcionando hasta Django 1.9.

django.forms.forms.get_declared_fields()

Django ya no utiliza esta función internamente. A pesar de ser una API privada, seguirá el ciclo normal de desprecación.

Consultas de Consulta Privadas

Las APIs privadas django.db.models.sql.where.WhereNode.make_atom() y django.db.models.sql.where.Constraint están desprecias en favor de la nueva API de consultas personalizadas: consultas personalizadas.

Características eliminadas en 1.7

Estas características han llegado al final de su ciclo de desprecación y se eliminan en Django 1.7. Consulte características desprecias-1.5 para obtener detalles, incluyendo cómo eliminar el uso de estas características.

  • django.utils.simplejson está eliminado.

  • django.utils.itercompat.product está eliminado.

  • INSTALLED_APPS y TEMPLATE_DIRS ya no se corrijieron desde una cadena simple en un tupla.

  • HttpResponse, SimpleTemplateResponse, TemplateResponse, render_to_response(), index(), y sitemap() ya no aceptan un argumento mimetype

  • HttpResponse consume inmediatamente su contenido si es un iterador.

  • Se eliminan la configuración de ajuste AUTH_PROFILE_MODULE y el método get_profile() en el modelo de usuario.

  • Se elimina el comando de gestión cleanup.

  • Se elimina el script daily_cleanup.py.

  • select_related() ya no tiene un argumento de palabra clave depth.

  • Las funciones get_warnings_state()/restore_warnings_state() del módulo django.test.utils y los métodos save_warnings_state()/ restore_warnings_state() en las clases que heredan de django.test.*TestCase se eliminan.

  • Se elimina el método check_for_test_cookie en la clase AuthenticationForm.

  • Se elimina la versión de django.contrib.auth.views.password_reset_confirm() que admite IDs de usuarios codificados en base36 (django.contrib.auth.views.password_reset_confirm_uidb36).

  • Se elimina el mix-in StrAndUnicode del módulo django.utils.encoding.