2008-10-04 7 views
61

Estoy teniendo problemas para resolver esto. Ahora mismo tengo algunos modelos que se ve algo así como esto:Señales de Django versus método de guardado anulado

def Review(models.Model) 
    ...fields... 
    overall_score = models.FloatField(blank=True) 

def Score(models.Model) 
    review = models.ForeignKey(Review) 
    question = models.TextField() 
    grade = models.IntegerField() 

Una revisión es tiene varios "puntuaciones", el overall_score es la media de las puntuaciones. Cuando se guarda una revisión o un puntaje, necesito volver a calcular el promedio general de puntuación. En este momento estoy usando un método de salvar anulado. ¿Habría algún beneficio al usar el despachador de señal de Django?

Respuesta

67

Las señales de guardar/eliminar son generalmente favorables en situaciones donde necesita realizar cambios que no son completamente específicos del modelo en cuestión, o podrían aplicarse a modelos que tienen algo en común, o podrían configurarse para su uso en modelos.

Una tarea común en los métodos reemplazados save es la generación automática de babosas desde algún campo de texto en un modelo. Ese es un ejemplo de algo que, si necesitara implementarlo para una serie de modelos, se beneficiaría del uso de una señal pre_save, donde el manejador de señal podría tomar el nombre del campo slug y el nombre del campo para generar el slug de . Una vez que tenga algo así en su lugar, cualquier funcionalidad mejorada que implemente también se aplicará a todos los modelos, p. buscando la babosa que está a punto de agregar para el tipo de modelo en cuestión, para garantizar la singularidad. Las aplicaciones reutilizables suelen beneficiarse del uso de señales. Si la funcionalidad que proporcionan se puede aplicar a cualquier modelo, generalmente (a menos que sea inevitable) no querrán que los usuarios tengan que modificar directamente sus modelos para beneficiarse de ellas. eso.

Con django-mptt, por ejemplo, he utilizado la señal de pre_save para gestionar un conjunto de campos que describen una estructura de árbol para el modelo que está a punto de ser creado o actualizado y la señal de pre_delete para eliminar detalles de la estructura de árbol para ser el objeto eliminado y todo su subárbol de objetos antes de él y se eliminan. Debido al uso de señales, los usuarios no tienen que agregar o modificar los métodos save o delete en sus modelos para realizar esta gestión, solo tienen que dejar que django-mptt sepa qué modelos quieren que administre.

3

Si usa señales, podrá actualizar la puntuación de la revisión cada vez que se guarde el modelo de puntaje relacionado. Pero si no necesito esa funcionalidad, no veo ninguna razón para poner esto en señal, eso es bastante relacionado con el modelo.

2

Es un tipo amable de denormalización. Mira esto pretty solution. Definición del campo de composición en el lugar.

-20

Las señales son útiles cuando tiene que ejecutar un proceso a largo plazo y no quiere bloquear a su usuario esperando a que se complete el guardado.

+8

No, señales de bloqueo a menos que desovan las discusiones de forma explícita. – muhuk

+8

@muhuk tiene razón, las señales bloquean sus procesos. Si desea evitar procesos bloqueados, use herramientas como gevent, apio u otras herramientas asincrónicas. – pydanny

+1

Le doy un -1 debido a los puntos de muhuk y pydanny. Parece que es un consejo totalmente equivocado. La solicitud no finalizará hasta que se complete el procesamiento de la señal. Así que el apio parece una buena solución, que es lo que normalmente uso en mis proyectos django. –

11

Se preguntó:

Habría algún ventajas a usar despachador señal de Django?

I encontraron esta en la documentación django:

métodos modelo se reemplaza no son llamados en operaciones a granel

Nota que el método delete() para un objeto no está necesariamente llama objetos cuando eliminación a granel utilizando un QuerySet o como resultado de una eliminación en cascada .Para garantizar que se ejecute la lógica de eliminación personalizada, puede usar las señales pre_delete y/o post_delete.

Desafortunadamente, no hay una solución al crear o actualizar objetos a granel, ya que ninguno de save(), pre_save y post_save son llamados.

Desde: Overriding predefined model methods

+2

La vista de la lista de administración de Django usa la eliminación masiva ... se confundió hasta que se encontró con este tidbit. –

+0

, también dice "Desafortunadamente, no hay una solución al crear o actualizar objetos de forma masiva, ya que no se llama a ninguno de los elementos save(), pre_save y post_save". - así que no creo que esto sea una compensación entre estos métodos. – Cory

Cuestiones relacionadas