Pregunta

Estoy teniendo problemas para envolver mi cabeza alrededor de esto. Ahora mismo tengo algunos modelos que se parecen a esto:

 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 tiene varias "puntuaciones", el puntaje general es el promedio de las puntuaciones. Cuando se guarda una revisión o un puntaje, debo recalcular el promedio general de puntuación. En este momento estoy usando un método de guardar anulado. ¿Habría algún beneficio al usar el despachador de señales de Django?

¿Fue útil?

Solución

Las señales de guardar / eliminar son generalmente favorables en situaciones en las que 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 todos los modelos .

Una tarea común en los métodos save anulados es la generación automatizada de slugs 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 con el uso de una señal pre_save , donde el controlador de señales podría tomar el nombre del campo slug y el nombre de El campo para generar el slug desde. Una vez que tenga algo como eso en su lugar, cualquier funcionalidad mejorada que ponga en su lugar también se aplicará a todos los modelos, por ejemplo, buscando la babosa que estás a punto de agregar para el tipo de modelo en cuestión, para asegurar la singularidad.

Las aplicaciones reutilizables a menudo se benefician del uso de señales: si la funcionalidad que brindan 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 él. .

Con django-mptt , por ejemplo, usé el pre_save señal para administrar un conjunto de campos que describen una estructura de árbol para el modelo que está a punto de crearse o actualizarse y la señal pre_delete para eliminar los detalles de la estructura de árbol para el objeto que se está eliminando y su Todo el 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 que esta administración se haga por ellos, solo tienen que dejar que django-mptt sabe qué modelos quieren que administre.

Otros consejos

Has preguntado:

¿Habría algún beneficio al usar el despachador de señales de Django?

Encontré esto en los documentos de django:

  

Los métodos de modelo anulados no se llaman en operaciones masivas

     

Tenga en cuenta que el método delete () para un objeto no se llama necesariamente   al eliminar objetos de forma masiva utilizando un QuerySet o como resultado de una   eliminar en cascada. Para garantizar que la lógica de eliminación personalizada se ejecute,   puede usar señales pre_delete y / o post_delete.

     

Lamentablemente, no hay una solución al crear o actualizar   objetos en masa, ya que ninguno de save (), pre_save y post_save son   llamado.

De: Anulación de métodos de modelo predefinidos

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

Es una especie de desnormalización. Mire esta solución bonita . Definición de campo de composición in situ.

Pequeña adición de Django docs sobre eliminación masiva (método .delete () en objetos QuerySet ):

  

Tenga en cuenta que esto, siempre que sea posible, se ejecutará exclusivamente en   SQL, y así los métodos delete () de instancias de objetos individuales serán   No necesariamente se llamará durante el proceso. Si ha proporcionado un   método personalizado () en una clase modelo y desea asegurarse de que sea   llamado, deberá & # 8220; manualmente & # 8221; eliminar instancias de ese modelo   (por ejemplo, mediante la iteración de un QuerySet y llamando a delete () en cada   objeto individualmente) en lugar de utilizar el método de eliminación masiva () de un   QuerySet.

https://docs.djangoproject.com/ es / 1.11 / topics / db / queries / # deleting-objects

Y actualización masiva (método .update () en los objetos QuerySet ):

  

Finalmente, comprenda que update () realiza una actualización a nivel de SQL y,   por lo tanto, no llama a ningún método save () en sus modelos, ni tampoco   emitir las señales pre_save o post_save (que son una consecuencia de   llamando a Model.save ()). Si desea actualizar un montón de registros para una   modelo que tiene un método personalizado de guardar (), recorrerlos y llamar a guardar ()

https://docs.djangoproject.com/en/ 2.1 / ref / models / querysets / # update

Las señales son útiles cuando tienes que ejecutar algún proceso a largo plazo y no quieres bloquear a tu usuario que espera a que se complete el proceso de guardar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top