Notas de lanzamiento de Django 1.2

17 de mayo de 2010.

Bienvenido a Django 1.2!

Casi un año en elaboración, Django 1.2 incluye una impresionante lista de nuevas características y muchos correcciones de bugs. Estas notas de lanzamiento cubren las nuevas características, así como los cambios importantes que debes tener en cuenta al actualizar desde Django 1.1 o versiones anteriores.

Resumen

Introduce Django 1.2 varias características grandes y importantes nuevas, incluyendo:

Estos son solo los resaltados; detalles completos y una lista completa de características pueden encontrarse a continuación.

Ver también

Django Advent cubrió la liberación de Django 1.2 con una serie de artículos y tutoriales que cubren algunas de las nuevas características en profundidad.

Donde sea posible, estas características se han introducido de manera compatible hacia atrás según nuestra política de estabilidad de API <doc:nuestra política de estabilidad de API </misc/api-stability>.

Sin embargo, un puñado de características han cambiado de maneras que, para algunos usuarios, serán incompatibles con el modo hacia atrás. Los cambios importantes son:

  • Se ha dejado de apoyar Python 2.3. Consulte las notas completas a continuación.

  • El nuevo marco de protección CSRF no es compatible con el sistema antiguo. Los usuarios del sistema antiguo no serán afectados hasta que el sistema antiguo sea eliminado en Django 1.4.

    Sin embargo, actualizar al nuevo marco de protección CSRF requiere unos pocos cambios importantes incompatibles con el modo hacia atrás, detallados en Protección CSRF, a continuación.

  • Los autores de clases personalizadas Field deben ser conscientes de que un número de métodos han tenido un cambio en la firma, detallado bajo get_db_prep_*() methods on Field, a continuación.

  • Las internas de las etiquetas de plantilla han cambiado algo; los autores de etiquetas de plantilla personalizadas que necesitan almacenar estado (por ejemplo, etiquetas de control de flujo personalizadas) deben asegurarse de que su código sigue las nuevas reglas para etiquetas de plantilla estatales.

  • Los decoradores user_passes_test(), login_required(), y permission_required(), desde django.contrib.auth solo se aplican a funciones y ya no funcionan en métodos. Hay una solución simple de una línea detallada en <user-passes-test-login-required-permission-required>.

De nuevo, estos son solo las características importantes que afectarán a los usuarios más. Los usuarios que actualizan desde versiones anteriores de Django se animan a consultar la lista completa de cambios incompatibles con el modo hacia atrás y la lista de características obsoletas.

Compatibilidad con Python

Mientras que no es una nueva característica, es importante tener en cuenta que Django 1.2 introduce la primera modificación en nuestra política de compatibilidad con Python desde el debut público inicial de Django. Las versiones anteriores de Django se probaron y se apoyaron en versiones de Python 2.x desde 2.3; sin embargo, Django 1.2 deja de ofrecer soporte oficial para Python 2.3. Como tal, la versión mínima de Python requerida para Django es ahora 2.4, y Django se prueba y se apoya en Python 2.4, 2.5 y 2.6, y se apoyará en el aún no lanzado Python 2.7.

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.4 o más nuevo como su versión predeterminada. Si todavía estás utilizando Python 2.3, sin embargo, necesitarás seguir utilizando Django 1.1 hasta que puedas actualizar; según nuestra política de soporte <internals/release-process>, Django 1.1 continuará recibiendo soporte de seguridad hasta la liberación de Django 1.3.

Se está desarrollando un plan general para el soporte de Python 2.x de Django y la transición eventual a Python 3.x, y se anunciará antes de la liberación de Django 1.3.

¿Qué hay de nuevo en Django 1.2

Soporte para bases de datos múltiples

Django 1.2 agrega la capacidad de utilizar más de una base de datos <topics/db/multi-db> en tu proyecto de Django. Las consultas se pueden emitir en una base de datos específica con el método using() en objetos QuerySet. Los objetos individuales se pueden guardar en una base de datos específica proporcionando un argumento using cuando llames a save().

Validación de modelos

Las instancias de modelo ahora tienen soporte para validar sus propios datos <validating-objects>, y tanto los campos del modelo como los formularios aceptan listas configurables de validadores <ref/validators> que especifican comportamiento de validación reutilizable y encapsulado. Sin embargo, tenga en cuenta que la validación debe realizarse explícitamente. Simplemente invocar el método save() de una instancia de modelo no realizará ninguna validación del datos de la instancia.

Protección mejorada contra ataques CSRF

Django ahora tiene una protección mucho mejorada contra ataques <ref/csrf> de Cross-Site Request Forgery (CSRF). Este tipo de ataque ocurre cuando un sitio web malicioso contiene un enlace, un botón de formulario o algún JavaScript que está destinado a realizar alguna acción en tu sitio web, utilizando las credenciales de un usuario conectado que visita el sitio malicioso en su navegador. Un tipo relacionado de ataque, «login CSRF,» donde un sitio atacante engaña al navegador del usuario para que se loguee en un sitio con las credenciales de alguien más, también está cubierto.

El marco de mensajes

Django ahora incluye un robusto y configurable marco de mensajes con soporte integrado para mensajería basada en cookies y sesiones, tanto para clientes anónimos como autenticados. El marco de mensajes reemplaza la API de mensajes de usuario descontinuada y permite almacenar temporalmente mensajes en una solicitud y recuperarlos para su visualización en una solicitud posterior (generalmente la siguiente).

Permisos a nivel de objeto

Se ha agregado una base para especificar permisos a nivel de objeto. Aunque no hay implementación de esto en el núcleo, un backend de autenticación personalizado puede proporcionar esta implementación y se utilizará por django.contrib.auth.models.User. Consulte los docs de autenticación para obtener más información.

Permisos para usuarios anónimos

Si proporcionas un backend de autenticación personalizado con supports_anonymous_user establecido en True, AnonymousUser verificará el backend por permisos, exactamente como ya lo hace User. Esto es útil para centralizar la gestión de permisos - las aplicaciones pueden delegar siempre la pregunta de si algo está permitido o no a la autorización/authenticación backend. Consulte los docs de autenticación para obtener más detalles.

Requisitos relajados para nombres de usuario

El campo username del modelo de usuario integrado User ahora permite un rango más amplio de caracteres, incluyendo los caracteres @, +, . y -.

Backends de correo electrónico

Puedes configurar ahora la forma en que Django envía correos electrónicos <topic-email-backends>. En lugar de utilizar SMTP para enviar todos los correos electrónicos, puedes elegir un backend de correo electrónico configurable para enviar mensajes. Si tu proveedor de alojamiento utiliza una sandbox o alguna otra técnica no-SMTP para enviar correo electrónico, ahora puedes construir un backend de correo electrónico que permita a las métodos estándar de envío de correo electrónico de Django utilizar esas facilidades.

This also makes it easier to debug mail sending. Django ships with backend implementations that allow you to send email to a file, to the console, or to memory. You can even configure all email to be thrown away.

La etiqueta de «Smart» if.

La etiqueta if ha sido actualizada para ser mucho más poderosa. Primero, hemos agregado soporte para operadores de comparación. Ya no tendrás que escribir:

{% ifnotequal a b %}
 ...
{% endifnotequal %}

Puedes hacer esto ahora:

{% if a != b %}
 ...
{% endif %}

En realidad, no hay razón para usar {% ifequal %} o {% ifnotequal %} más, a menos que seas del tipo nostálgico.

Los operadores soportados son ==, !=, <, >, <=, >=, in y not in, todos los cuales funcionan como los operadores de Python, además de and, or y not, que ya estaban soportados.

También se pueden utilizar filtros en la expresión if. Por ejemplo:

<div
  {% if user.email|lower == message.recipient|lower %}
    class="highlight"
  {% endif %}
>{{ message }}</div>

Caché de plantillas

En versiones anteriores de Django, cada vez que renderizabas una plantilla, se recargaba desde disco. En Django 1.2, puedes usar un cargador de plantillas caché para cargar las plantillas una sola vez y luego cachear el resultado para cada renderizado posterior. Esto puede dar lugar a una mejora significativa en rendimiento si tus plantillas están divididas en muchos subplantillas más pequeñas (utilizando los etiquetas {% extends %} o {% include %}).

Como efecto secundario, ahora es mucho más fácil apoyar lenguajes de plantilla no-Django.

Cargadores basados en clases de plantillas

Como parte de los cambios realizados para introducir el **caching de plantillas**_ y siguiendo una tendencia general en Django, la API de cargadores de plantillas ha sido modificada para utilizar mecanismos de carga de plantillas encapsulados en clases de Python en lugar de funciones, el único método disponible hasta Django 1.1.

Todas las cargadoras de plantillas shipped with Django han sido portadas a la nueva API pero aún implementan la API basada en funciones y la maquinaria central de plantillas todavía acepta cargadores basados en funciones (integrados o de terceros) por lo que no hay necesidad inmediata de modificar tu TEMPLATE_LOADERS configuración en proyectos existentes, las cosas seguirán funcionando si lo dejas sin tocar hasta y incluyendo la versión Django 1.3.

Si has desarrollado tus propios cargadores de plantillas personalizados, te sugerimos considerar portarlos a una implementación basada en clases porque el código para la compatibilidad hacia atrás con los cargadores basados en funciones comienza su proceso de deprecación en Django 1.2 y se eliminará en Django 1.4. Hay una descripción de la API que deben implementar estas clases de cargador en la referencia de la API de plantillas y también puedes examinar el código fuente de los cargadores incluidos con Django.

Claves naturales en fijaciones de datos.

Fijaciones pueden ahora hacer referencia a objetos remotos utilizando Claves naturales. Este esquema de búsqueda es una alternativa al normal objeto de referencia basado en la clave primaria en una fijación, mejorando la legibilidad y resolviendo problemas que hacen referencia a objetos cuyo valor de clave primaria puede no ser predecible o conocido.

Fallo rápido para pruebas

Ambas la subcomandante test de django-admin.py y el script runtests.py utilizado para ejecutar la suite de pruebas propia de Django ahora admiten una opción --failfast. Cuando se especifica esta opción, ésta hace que el ejecutor de pruebas salga después de encontrar un fallo en lugar de continuar con la ejecución de las pruebas. Además, se ha mejorado el manejo del atajo Ctrl-C durante la ejecución de las pruebas para hacer que se produzca una salida suave de la ejecución de las pruebas que informe sobre los detalles de las pruebas ejecutadas antes de la interrupción.

BigIntegerField

Los modelos pueden utilizar ahora un tipo de campo BigIntegerField de 64 bits: BigIntegerField.

Mejoras de localización

La fusión internacional de Django ha sido ampliada con formateo y procesamiento de formularios conscientes del idioma. Esto significa que, si está habilitado, las fechas y números en los templates se mostrarán utilizando el formato especificado para el idioma actual. Django también utilizará formatos locales cuando parsee datos en formularios. Consulta Format localization para obtener más detalles.

readonly_fields en ModelAdmin

django.contrib.admin.ModelAdmin.readonly_fields se ha agregado para permitir campos no editables en páginas de agregar/cambiar para modelos e inlines. Los valores de campo y calculados pueden ser mostrados junto a los campos editables.

Resaltado de sintaxis personalizable

Ahora puedes utilizar la variable de entorno DJANGO_COLORS para modificar o deshabilitar los colores utilizados por django-admin.py para proporcionar resaltado de sintaxis.

Flujos de syndication como vistas

Flujos de syndication pueden ahora ser utilizados directamente como vistas en tu URLconf. Esto significa que puedes mantener el control completo sobre la estructura de URL de tus flujos. Al igual que cualquier otra vista, las vistas de flujos reciben un objeto request, por lo que puedes hacer cualquier cosa que normalmente harías con una vista, como controlar el acceso basado en usuarios o hacer que un flujo sea una URL nombrada.

GeoDjango

La característica más significativa nueva para GeoDjango en 1.2 es el soporte para múltiples bases de datos espaciales. Como resultado, las siguientes bases de datos espaciales ahora están incluidas:

  • django.contrib.gis.db.backends.postgis

  • django.contrib.gis.db.backends.mysql

  • django.contrib.gis.db.backends.oracle

  • django.contrib.gis.db.backends.spatialite

GeoDjango ahora admite las ricas capacidades agregadas en la versión de liberación PostGIS 1.5. Nuevas características incluyen el soporte para el tipo de dato geografía y la habilitación de consultas de distancia <distance-queries> con geometrías no puntales en sistemas de coordenadas geográficas.

Se agregó el soporte a campos de geometría 3D, que se puede habilitar estableciendo el parámetro dim a 3 en tu campo GeometryField. Se agregaron como parte de esta característica la función agregada Extent3D y el método extent3d() del conjunto de consultas GeoQuerySet.

Los métodos force_rhr(), reverse_geom() y geohash() del conjunto de consultas GeoQuerySet son nuevos.

Se actualizó la interfaz GEOS para utilizar funciones de biblioteca C seguras en hilos cuando estén disponibles en la plataforma.

La interfaz GDAL ahora permite al usuario establecer un spatial_filter en las características devueltas al iterar sobre una Layer.

Finalmente, la documentación de GeoDjango <GeoDjango’s documentation </ref/contrib/gis/index>> ahora está incluida con Django y ya no se hospeda separadamente en geodjango.org.

Se han introducido nuevos caracteres de especificación del formato para la plantilla now: c y u

El argumento de la now ha ganado dos nuevos caracteres de formato: c para especificar que un valor de fecha y hora debe formatearse en el formato ISO 8601, y u que permite la salida de la parte de microsegundos de un valor de fecha o hora.

Estos también están disponibles en otras partes como los filtros de plantilla date y time, la biblioteca de etiquetas de plantilla humanize y el nuevo marco de trabajo de localización de formato _.

Cambios incompatibles con la versión 1.2

Donde sea posible, las nuevas características se han introducido de manera compatible hacia atrás según la política de estabilidad de API /misc/api-stability. Esto significa que prácticamente todo el código existente que funcionaba con Django 1.1 seguirá funcionando con Django 1.2; sin embargo, ese código comenzará a emitir advertencias (consulte los detalles más abajo).

Sin embargo, un puñado de características han cambiado de maneras que, para algunos usuarios, serán incompatibles hacia atrás de manera inmediata. Los cambios se detallan a continuación.

Protección CSRF

Hemos realizado grandes cambios en la forma en que funciona la protección CSRF, detallados en la documentación de CSRF. A continuación, se presentan los cambios principales de los cuales debes ser consciente:

  • CsrfResponseMiddleware y CsrfMiddleware han sido deprecados y se eliminarán completamente en Django 1.4, a favor de una etiqueta de plantilla que debe insertarse en las formas.

  • Los textos traducidos son:

    Documentación eliminada

    Las notas de actualización han sido eliminadas en la documentación actual de Django. Por favor, consulta los docs de Django 1.3 o versiones anteriores para encontrar estas instrucciones.

  • CsrfViewMiddleware está incluido por defecto en MIDDLEWARE_CLASSES. Esto activa la protección CSRF por defecto, por lo que las vistas que aceptan solicitudes POST deben ser escritas para funcionar con el middleware. Las instrucciones sobre cómo hacer esto se encuentran en los docs de CSRF.

  • Todas las CSRF han sido movidas desde contrib a core (con importaciones compatibles hacia atrás en las ubicaciones antiguas, que están desaconsejadas y dejarán de ser soportadas en Django 1.4).

get_db_prep_*() métodos en Field

Antes de Django 1.2, un campo personalizado tenía la opción de definir varias funciones para apoyar la conversión de valores Python a valores compatibles con la base de datos. Un campo personalizado podría verse algo así:

class CustomModelField(models.Field):
    ...

    def db_type(self): ...

    def get_db_prep_save(self, value): ...

    def get_db_prep_value(self, value): ...

    def get_db_prep_lookup(self, lookup_type, value): ...

En 1.2, estos tres métodos han sufrido un cambio en el prototipo, y dos métodos adicionales se han introducido:

class CustomModelField(models.Field):
    ...

    def db_type(self, connection): ...

    def get_prep_value(self, value): ...

    def get_prep_lookup(self, lookup_type, value): ...

    def get_db_prep_save(self, value, connection): ...

    def get_db_prep_value(self, value, connection, prepared=False): ...

    def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): ...

Estos cambios son necesarios para apoyar múltiples bases de datos – db_type y get_db_prep_* ya no pueden hacer suposiciones sobre la base de datos para la que está preparando. El argumento connection ahora proporciona a los métodos de preparación con la conexión específica para la cual el valor se está preparando.

Los dos nuevos métodos existen para diferenciar las necesidades generales de preparación de datos de las necesidades que son específicas de una base de datos. El argumento prepared se utiliza para indicar a los métodos de preparación de la base de datos si se ha realizado una preparación de valor genérica. Si un valor no preparado (es decir, prepared=False) se proporciona a las llamadas get_db_prep_*(), deben invocar los correspondientes llamados get_prep_*() para realizar la preparación de datos genéricos.

Nos hemos proporcionado funciones de conversión que transparentemente convertirán las funciones que siguen el antiguo prototipo en funciones compatibles con el nuevo prototipo. Sin embargo, estas funciones de conversión se eliminarán en Django 1.4, por lo que deberías actualizar tus definiciones de Field para utilizar el nuevo prototipo tan pronto como sea posible.

Si tus métodos get_db_prep_*() no utilizaban la conexión a la base de datos, deberías poder actualizar renombrando get_db_prep_value() a get_prep_value() y get_db_prep_lookup() a get_prep_lookup(). Si requieres conversiones específicas del motor de base de datos, entonces necesitarás proporcionar una implementación get_db_prep_* que utilice el argumento connection para resolver valores específicos del motor.

Marcadores de plantilla estatales

Los marcadores de plantilla que almacenan el estado de la renderización en su subclase Node siempre han sido vulnerables a problemas de seguridad entre hilos y otros; sin embargo, a partir de Django 1.2, también pueden causar problemas cuando se utilizan con el nuevo cargador de plantillas caché.

Todos los marcadores de plantilla integrados de Django son seguros para usar con el cargador caché, pero si estás utilizando marcadores de plantilla personalizados que provienen de paquetes de terceros o de tu propio código, deberías asegurarte de que la implementación Node para cada etiqueta es segura entre hilos. Para obtener más información, consulte consideraciones sobre seguridad entre hilos de marcadores de plantilla.

También podrías necesitar actualizar tus plantillas si estabas contando con la implementación de los marcadores de plantilla de Django no ser seguros entre hilos. El marcador cycle es el más probable a estar afectado de esta manera, especialmente cuando se utiliza en conjunto con el marcador include. Considera el siguiente fragmento de plantilla:

{% for object in object_list %}
    {% include "subtemplate.html" %}
{% endfor %}

con un subtemplate.html que lee:

{% cycle 'even' 'odd' %}

Utilizando el renderizador no seguro entre hilos, pre-Django 1.2, esto produciría:

even odd even odd ...

Utilizando el renderizador seguro entre hilos Django 1.2, en su lugar obtendrás:

even even even even ...

Esto es porque cada renderización del marcador include es una renderización independiente. Cuando el marcador cycle no era seguro entre hilos, el estado del marcador cycle se filtraba entre múltiples renderizaciones del mismo marcador include. Ahora que el marcador cycle es seguro entre hilos, esta filtración ya no ocurre.

user_passes_test, login_required y permission_required

django.contrib.auth.decorators proporciona los decoradores login_required, permission_required y user_passes_test. Anteriormente era posible utilizar estos decoradores tanto en funciones (donde el primer argumento es “request”) como en métodos (donde el primer argumento es “self” y el segundo argumento es “request”). Desafortunadamente, se descubrieron defectos en el código que los apoyaba: solo funcionan en circunstancias limitadas y producen errores muy difíciles de depurar cuando no funcionan.

Por esta razón, se ha eliminado el comportamiento “auto adapt”, y si estás utilizando estos decoradores en métodos, necesitarás aplicar manualmente django.utils.decorators.method_decorator() para convertir el decorador a uno que funcione con métodos. Por ejemplo, cambiarías código de este tipo:

class MyClass(object):
    @login_required
    def my_view(self, request):
        pass

a esto:

from django.utils.decorators import method_decorator


class MyClass(object):
    @method_decorator(login_required)
    def my_view(self, request):
        pass

o:

from django.utils.decorators import method_decorator

login_required_m = method_decorator(login_required)


class MyClass(object):
    @login_required_m
    def my_view(self, request):
        pass

Para aquellos que han estado siguiendo la rama de desarrollo, esta modificación también se aplica a otros decoradores introducidos desde 1.1, incluyendo csrf_protect, cache_control y cualquier cosa creada utilizando decorator_from_middleware.

Cambios en el if tag

Debido a nuevas características en la etiqueta de plantilla if, ya no acepta “and”, “or” y “not” como nombres válidos de variables. Anteriormente, estos strings se podían utilizar como nombres de variables. Ahora, el estado de palabra clave siempre se aplica, y código de plantilla como {% if not %} o {% if and %} lanzará un TemplateSyntaxError. Además, “in” es una nueva palabra clave y por lo tanto no es un nombre válido de variable en esta etiqueta.

LazyObject

LazyObject es una clase de utilidad no documentada pero a menudo utilizada para envolver de manera relajada otros objetos del tipo desconocido.

En Django 1.1 y versiones anteriores, manejo la introspección de manera no estándar, dependiendo de que los objetos envueltos implementen un método público llamado get_all_members(). Dado que esto podría fácilmente provocar colisiones de nombres, se ha cambiado a utilizar el método de introspección estándar de Python, involucrando __members__ y __dir__().

Si utilizaste LazyObject en tu propio código y implementaste el método get_all_members() para objetos envueltos, necesitarás hacer un par de cambios:

Primero, si tu clase no tiene requisitos especiales para la introspección (es decir, no has implementado __getattr__() o otros métodos que permiten atributos no descubribles por mecanismos normales), puedes simplemente eliminar el método get_all_members(). La implementación predeterminada en LazyObject hará lo correcto.

Si tienes requisitos más complejos para la introspección, renombra primero el método get_all_members() a __dir__(). Este es el método de introspección estándar para Python 2.6 y superior. Si requieres soporte para versiones de Python anteriores a 2.6, agrega el siguiente código a la clase:

__members__ = property(lambda self: self.__dir__())

__dict__ en instancias de modelo

Históricamente, el atributo __dict__ de una instancia de modelo ha contenido solo atributos correspondientes a los campos de un modelo.

Para apoyar múltiples configuraciones de base de datos, Django 1.2 ha agregado un atributo _state a las instancias de objeto. Este atributo aparecerá en __dict__ para una instancia de modelo. Si tu código depende de iterar sobre __dict__ para obtener una lista de campos, debes estar preparado para manejar o filtrar el atributo _state.

Estatus de salida del ejecutor de pruebas

El código de estado de salida del ejecutor de pruebas (tests/runtests.py y python manage.py test) ya no representa el número de pruebas fallidas, porque una falla de 256 o más pruebas resultaba en un código de estado de salida incorrecto. El código de estado de salida para el ejecutor de pruebas es ahora 0 para éxito (sin pruebas fallidas) y 1 para cualquier número de pruebas fallidas. Si es necesario, el número de pruebas fallidas se puede encontrar al final del output del ejecutor de pruebas.

ModelForm.is_valid() y ModelForm.errors

Mucha de la validación para ModelForms se ha movido hacia abajo al nivel del modelo. Como resultado, la primera vez que llames a ModelForm.is_valid(), accedas a ModelForm.errors o desencadenes la validación de formulario, tu modelo será limpiado en lugar. Esta conversión solía suceder cuando el modelo se guardaba. Si necesitas una instancia no modificada de tu modelo, debes pasar una copia al constructor de ModelForm.

BooleanField en MySQL

En versiones anteriores de Django, un campo de modelo BooleanField bajo MySQL devolvía su valor como 1 o 0, en lugar de True o False; para la mayoría de las personas esto no era un problema porque bool es una subclase de int en Python. En Django 1.2, sin embargo, BooleanField en MySQL devuelve correctamente un verdadero bool. El único momento en que esto debería ser un problema es si estabas esperando la representación literal de un BooleanField para imprimir 1 o 0.

Cambios en la interpretación de max_num en FormSets

Como parte de las mejoras realizadas en el manejo de los FormSets, se ha cambiado ligeramente el valor por defecto y la interpretación del parámetro max_num para las funciones django.forms.formsets.formset_factory() y django.forms.models.modelformset_factory(). Este cambio también afecta la forma en que se utiliza el argumento max_num para objetos de administración inline.

Anteriormente, el valor por defecto para max_num era 0 (cero). Los FormSets utilizaban luego el valor booleano de max_num para determinar si se debía imponer un límite en el número de formularios generados. El valor por defecto de 0 significaba que no había límite por defecto en el número de formularios en un FormSet.

A partir de 1.2, el valor por defecto para max_num se ha cambiado a None, y los FormSets diferenciarán entre un valor de None y un valor de 0. Un valor de None indica que no se debe imponer límite en el número de formularios; un valor de 0 indica que se debe imponer un máximo de 0 formularios. Esto no significa necesariamente que no se mostrarán formularios – consulte la documentación del ModelFormSet para obtener más detalles.

Si estabas especificando manualmente un valor de 0 para max_num, deberás actualizar tus definiciones de FormSet y/o administración.

Ver también

1.2-js-assistidos-inlines

email_re

Una expresión regular no documentada para validar direcciones de correo electrónico ha sido movida desde django.form.fields a django.core.validators. Deberás actualizar tus importaciones si la estás utilizando.

Features deprecados en 1.2

Finalmente, Django 1.2 deprecia algunas características de versiones anteriores. Estas características todavía están soportadas, pero se eliminarán gradualmente durante los próximos ciclos de liberación.

El código que aprovecha alguna de las características a continuación levantará una PendingDeprecationWarning en Django 1.2. Esta advertencia será silenciosa por defecto, pero puede ser habilitada utilizando el módulo warnings de Python, o ejecutando Python con la bandera -Wd o -Wall.

En Django 1.3, estas advertencias se convertirán en una DeprecationWarning, que no es silenciosa. En Django 1.4, el soporte para estas características será removido por completo.

Ver también

Para obtener más detalles, consulte la documentación Django’s proceso de liberación y nuestro cronograma de deprecación.

Especificar bases de datos

Antes de Django 1.2, Django utilizaba una serie de configuraciones para controlar el acceso a una base de datos única. Django 1.2 introduce soporte para múltiples bases de datos, y como resultado, la forma en que se definen las configuraciones de base de datos ha cambiado.

Cualquier archivo de configuración existente de Django seguirá funcionando como se espera hasta Django 1.4. Hasta entonces, las configuraciones de base de datos antiguas se traducirán automáticamente al formato nuevo.

En el formato antiguo (pre 1.2), tenías una serie de configuraciones DATABASE_ en tu archivo de configuración. Por ejemplo:

DATABASE_NAME = "test_db"
DATABASE_ENGINE = "postgresql_psycopg2"
DATABASE_USER = "myusername"
DATABASE_PASSWORD = "s3krit"

Estas configuraciones ahora están en un diccionario llamado DATABASES. Cada elemento del diccionario corresponde a una conexión de base de datos única, con el nombre 'default' que describe la conexión de base de datos predeterminada. Los nombres de configuración también se han acortado. Las configuraciones de muestra anteriores ahora tendrían este aspecto:

DATABASES = {
    "default": {
        "NAME": "test_db",
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "USER": "myusername",
        "PASSWORD": "s3krit",
    }
}

Este afecta las siguientes configuraciones:

Ajuste antiguo

Ajuste nuevo

DATABASE_ENGINE

MOTOR

DATABASE_HOST

:host:`HOST`

DATABASE_NAME

NOMBRE

DATABASE_OPTIONS

OPCIONES

CONTRASEÑA_DE_BASE_DE_DATOS

CONTRASEÑA

PUERTO_DE_BASE_DE_DATOS

PUERTO

USUARIO_DE_BASE_DE_DATOS

USUARIO

CARACTERES_DE_CONSULTA_DE_PRUEBA

CARACTERES_DE_CONSULTA_DE_PRUEBA

ORDENACIÓN_DE_CONSULTA_DE_PRUEBA

TEST_COLLACIÓN

NOMBRE_DE_LA_BASE_DE_DATOS_TEST

NOMBRE_DE_PRUEBA

Estas modificaciones también son necesarias si has creado manualmente una conexión a la base de datos utilizando DatabaseWrapper() desde el backend de base de datos de tu elección.

Además del cambio en la estructura, Django 1.2 elimina el manejo especial para los backends de base de datos integrados. Todos los backends de base de datos deben especificarse ahora mediante un nombre de módulo cualificado (es decir, django.db.backends.postgresql_psycopg2, en lugar de solo postgresql_psycopg2).

Backend de base de datos postgresql

La biblioteca psycopg1 no ha sido actualizada desde octubre de 2005. Como resultado, el backend de base de datos postgresql, que utiliza esta biblioteca, ha sido descontinuado.

Si estás utilizando actualmente el backend postgresql, debes migrar a utilizar el backend postgresql_psycopg2. Para actualizar tu código, instala la biblioteca psycopg2 y cambia la configuración ENGINE para utilizar django.db.backends.postgresql_psycopg2.

Middleware de respuesta CSRF

CsrfResponseMiddleware, el middleware que insertaba automáticamente tokens CSRF en las formas POST de las páginas salientes, ha sido descontinuado a favor de un método mediante etiquetas de plantilla (consultar arriba), y será eliminado completamente en Django 1.4. CsrfMiddleware, que incluye la funcionalidad de CsrfResponseMiddleware y CsrfViewMiddleware, también ha sido descontinuada.

También, el módulo CSRF ha sido movido de contrib a core y los antiguos imports están descontinuados, como se describe en las notas de actualización.

Documentación eliminada

Las notas de actualización han sido eliminadas en la documentación actual de Django. Por favor, consulta los docs de Django 1.3 o versiones anteriores para encontrar estas instrucciones.

SMTPConnection

La clase SMTPConnection está descontinuada en favor de una API de backend de correo electrónico genérica. El código antiguo que instanciaba explícitamente una instancia de un SMTPConnection:

from django.core.mail import SMTPConnection

connection = SMTPConnection()
messages = get_notification_email()
connection.send_messages(messages)

…debería llamar ahora a la función get_connection() para instanciar una conexión de correo electrónico genérica:

from django.core.mail import get_connection

connection = get_connection()
messages = get_notification_email()
connection.send_messages(messages)

Según el valor del parámetro de configuración EMAIL_BACKEND, esto puede no devolver una conexión SMTP. Si requieres explícitamente una conexión SMTP con la que enviar correo electrónico, puedes solicitar explícitamente una conexión SMTP:

from django.core.mail import get_connection

connection = get_connection("django.core.mail.backends.smtp.EmailBackend")
messages = get_notification_email()
connection.send_messages(messages)

Si tu llamada a construir una instancia de SMTPConnection requería argumentos adicionales, esos argumentos se pueden pasar al llamado a la función get_connection():

connection = get_connection(
    "django.core.mail.backends.smtp.EmailBackend", hostname="localhost", port=1234
)

API de Mensajes del Usuario

La API para almacenar mensajes en el modelo de mensaje del usuario (a través de user.message_set.create) está descontinuada y se eliminará en Django 1.4 según el proceso de liberación estándar <internals/release-process>.

Para actualizar tu código, necesitas reemplazar cualquier instancia de esto:

user.message_set.create("a message")

…por lo siguiente:

from django.contrib import messages

messages.add_message(request, messages.INFO, "a message")

Además, si utilizas la método, debes reemplazar lo siguiente:

for message in user.get_and_delete_messages():
    ...

…con:

from django.contrib import messages

for message in messages.get_messages(request):
    ...

Para obtener más información, consulta la documentación completa de mensajes: messages. Debes comenzar a actualizar tu código para utilizar la nueva API inmediatamente.

Funciones auxiliares para formato de fecha

django.utils.translation.get_date_formats() y django.utils.translation.get_partial_date_formats() han sido deprecados en favor de las llamadas adecuadas a django.utils.formats.get_format(), que es consciente del lugar cuando USE_L10N está establecido en True, y cae hacia los ajustes por defecto si se establece en False.

Obtén diferentes formatos de fecha en lugar de escribir esto:

from django.utils.translation import get_date_formats

date_format, datetime_format, time_format = get_date_formats()

…uso:

from django.utils import formats

date_format = formats.get_format("DATE_FORMAT")
datetime_format = formats.get_format("DATETIME_FORMAT")
time_format = formats.get_format("TIME_FORMAT")

O cuando se formatea directamente un valor de fecha:

from django.utils import formats

value_formatted = formats.date_format(value, "DATETIME_FORMAT")

La misma regla se aplica a las variables globales encontradas en django.forms.fields.

  • DEFAULT_DATE_INPUT_FORMATS

  • DEFAULT_TIME_INPUT_FORMATS

  • FORMATOS_DE_INGRESO_DE_HORA_POR_DEFECTO

Use django.utils.formats.get_format() to get the appropriate formats.

Ejecutores de pruebas basados en funciones

Django 1.2 cambia las herramientas del ejecutor de pruebas a un enfoque basado en clases. Los ejecutores de pruebas basados en funciones antiguos todavía funcionarán, pero deberían actualizarse para utilizar el nuevo ejecutores de pruebas basados en clases.

Feed en django.contrib.syndication.feeds

La clase django.contrib.syndication.feeds.Feed ha sido reemplazada por la clase django.contrib.syndication.views.Feed. La antigua clase feeds.Feed está deprecada y será eliminada en Django 1.4.

La nueva clase tiene una API casi idéntica, pero permite que las instancias se utilicen como vistas. Por ejemplo, considere el uso del viejo marco en el siguiente URLconf:

from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory

feeds = {
    "latest": LatestEntries,
    "categories": LatestEntriesByCategory,
}

urlpatterns = patterns(
    "",
    # ...
    (
        r"^feeds/(?P<url>.*)/$",
        "django.contrib.syndication.views.feed",
        {"feed_dict": feeds},
    ),
    # ...
)

Al utilizar la nueva clase Feed, estas fuentes pueden ser desplegadas directamente como vistas:

from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory

urlpatterns = patterns(
    "",
    # ...
    (r"^feeds/latest/$", LatestEntries()),
    (r"^feeds/categories/(?P<category_id>\d+)/$", LatestEntriesByCategory()),
    # ...
)

Si actualmente utiliza la vista feed(), la clase LatestEntries a menudo no necesitaría modificarse más que heredando de la nueva Feed clase. La excepción es si Django estaba trabajando automáticamente el nombre del template para utilizar para renderizar los elementos de descripción y título de la fuente (si no se especificaban las atributos title_template y description_template). Debe asegurarse de siempre especificar los atributos title_template y description_template, o proporcionar métodos item_title() y item_description().

Sin embargo, LatestEntriesByCategory utiliza el método get_object() con la argumento bits para especificar una categoría específica a mostrar. En la nueva clase Feed, el método get_object() toma un objeto request y argumentos de la URL, por lo que se vería así:

from django.contrib.syndication.views import Feed
from django.shortcuts import get_object_or_404
from myproject.models import Category


class LatestEntriesByCategory(Feed):
    def get_object(self, request, category_id):
        return get_object_or_404(Category, id=category_id)

    # ...

Además, el método get_feed() en las clases Feed ahora toman diferentes argumentos, lo que puede afectar a usted si utiliza directamente las clases Feed. En lugar de tomar solo un argumento url opcional, ahora toma dos argumentos: el objeto devuelto por su propio método get_object() y el objeto request actual.

Para tener en cuenta que las clases Feed no están inicializadas para cada solicitud, el método __init__() ahora no toma argumentos por defecto. Anteriormente tomaría la slug de la URL y el objeto request.

De acuerdo con las mejores prácticas de RSS , los feeds RSS incluirán ahora un elemento atom:link . Es posible que deba actualizar tus pruebas para tener en cuenta esto.

Para obtener más información, consulte la documentación completa del framework de syndication.

IDs de mensajes técnicos

Hasta la versión 1.1 Django utilizaba IDs de mensajes técnicos para proporcionar a los localizadores la posibilidad de traducir formatos de fecha y hora. Eran cadenas de traducción transponibles <cadena de traducción> que podían reconocerse porque todas estaban en mayúsculas (por ejemplo DATETIME_FORMAT, DATE_FORMAT, TIME_FORMAT). Han sido descontinuados a favor del nuevo Format localization infraestructura que permite a los localizadores especificar esa información en un archivo formats.py en el directorio correspondiente django/conf/locale/<nombre de la ubicación>/.

GeoDjango

Para permitir el soporte para múltiples bases de datos, se cambiaron sustancialmente las internas de base de datos GeoDjango. El cambio más grande que afecta a la compatibilidad hacia atrás es que el módulo django.contrib.gis.db.backend fue renombrado a django.contrib.gis.db.backends, donde ahora existen los backends de bases de datos espaciales completos <spatial-backends> . Las siguientes secciones proporcionan información sobre las APIs más populares que fueron afectadas por estos cambios.

SpatialBackend

Antes de la creación de los backends espaciales separados, el objeto django.contrib.gis.db.backend.SpatialBackend se proporcionaba como una abstracción para introspeccionar las capacidades de la base de datos espacial. Todas las propiedades y rutinas proporcionadas por SpatialBackend ahora son parte del atributo ops del backend de base de datos.

El módulo antiguo django.contrib.gis.db.backend sigue siendo proporcionado para el acceso a una versión compatible con versiones anteriores de la conexión de base de datos espacial, que es solo un alias al módulo ops de la conexión de base de datos espacial por defecto.

Los usuarios que se estaban basando en módulos y objetos no documentados dentro de django.contrib.gis.db.backend, más bien en las abstracciones proporcionadas por SpatialBackend, deben modificar su código. Por ejemplo, la siguiente importación que funcionaría en 1.1 y versiones anteriores:

from django.contrib.gis.db.backend.postgis import PostGISAdaptor

Debería ser cambiada a:

from django.db import connection

PostGISAdaptor = connection.ops.Adapter

SpatialRefSys y modelos de GeometryColumns

En versiones anteriores de GeoDjango, el módulo django.contrib.gis.db.models tenía modelos SpatialRefSys y GeometryColumns para consultar las tablas de metadatos espaciales OGC spatial_ref_sys y geometry_columns, respectivamente.

Aunque estos alias siguen siendo proporcionados, solo están disponibles para la conexión de base de datos por defecto y existen solo si la conexión por defecto está utilizando un backend de base de datos espacial compatible.

Nota

Porque la estructura de las tablas de metadatos espaciales OGC difiere entre bases de datos espaciales, los modelos SpatialRefSys y GeometryColumns ya no pueden estar asociados con el nombre de aplicación gis''.  Por lo tanto, no se devolverán modelos cuando se utilice el método ``get_models en el ejemplo siguiente:

>>> from django.db.models import get_app, get_models
>>> get_models(get_app("gis"))
[]

Para obtener los correctos SpatialRefSys y GeometryColumns para tu base de datos espacial, utiliza los métodos proporcionados por el backend espacial.

>>> from django.db import connections
>>> SpatialRefSys = connections["my_spatialite"].ops.spatial_ref_sys()
>>> GeometryColumns = connections["my_postgis"].ops.geometry_columns()

Nota

Cuando uses los modelos devueltos desde el método spatial_ref_sys() y geometry_columns(), todavía necesitarás utilizar la etiqueta de base de datos correcta cuando consultes en la conexión no por defecto. En otras palabras, para asegurarte de que los modelos en el ejemplo anterior utilicen la base de datos correcta:

sr_qs = SpatialRefSys.objects.using("my_spatialite").filter(...)
gc_qs = GeometryColumns.objects.using("my_postgis").filter(...)

El código no es un código de idioma

La traducción de los textos es la siguiente:

Cargadores de plantillas basados en funciones

Django 1.2 cambia el mecanismo de carga de plantillas a un enfoque basado en clases. Los cargadores de plantillas basados en funciones antiguos todavía funcionarán, pero deberían actualizarse para utilizar los nuevos cargadores de plantillas basados en clases.