python - signal - Cuándo usar pre_save, save, post_save en django?
receiver signal django (3)
Veo que puedo anular o definir pre_save, save, post_save
para hacer lo que quiero cuando se guarda una instancia del modelo.
¿Cuál es el preferido en qué situación y por qué?
Haré todo lo posible para explicarlo con un ejemplo:
pre_save
y post_save
son signals que envía el modelo. En palabras más simples, se llaman las acciones a tomar antes o después de save
el modelo.
Un save
desencadena los siguientes pasos
- Emite una señal de pre-guardado.
- Preprocesar los datos.
- La mayoría de los campos no procesan previamente: los datos de campo se guardan tal como están.
- Prepare los datos para la base de datos.
- Inserta los datos en la base de datos.
- Emite una señal de guardado.
Django proporciona una forma de anular estas señales.
Ahora,
pre_save
señal pre_save
puede ser anulada para algún procesamiento antes de que ocurra el guardado real en la base de datos. Ejemplo: (No conozco un buen ejemplo de dónde pre_save
sería ideal en la parte superior de mi cabeza)
ModelA
que tiene un ModelA
que almacena referencias a todos los objetos del ModelB
que aún no se han editado. Para esto, puede registrar una señal pre_save
para notificar a ModelA
justo antes de que se ModelB
al método save
ModelB
(nada le impide registrar una señal post_save
también).
Ahora, el método de save
(no es una señal) del modelo se llama: de manera predeterminada, cada modelo tiene un método de save
, pero puede anularlo:
class ModelB(models.Model):
def save(self):
#do some custom processing here: Example: convert Image resolution to a normalized value
super(ModelB, self).save()
Entonces, puedes registrar la señal post_save
(Esto es más usado que pre_save
)
Un caso de uso común es la creación de objetos UserProfile
cuando se crea un objeto User
en el sistema.
Puede registrar una señal post_save
que crea un objeto UserProfile
que corresponde a cada User
en el sistema.
Las señales son una forma de mantener las cosas modulares y explícitas. (Notifique explícitamente a ModelA
si ModelA
o cambio algo en el ModelB
)
Pensaré en ejemplos más concretos del mundo real para intentar responder mejor a esta pregunta. Mientras tanto, espero que esto te ayude
No te olvides del riesgo de recurrencias. Si usa el método post_save con la llamada a instance.save () , en lugar del método .update, debe desconectar la señal de post_save :
Desconexión de señal (receiver = None, sender = None, dispatch_uid = None) [fuente] Para desconectar un receptor de una señal, llame a Signal.disconnect (). Los argumentos son como se describe en Signal.connect (). El método devuelve True si se desconectó un receptor y False si no.
El argumento del receptor indica que el receptor registrado debe desconectarse. Puede ser None si dispatch_uid se usa para identificar al receptor.
... y conectarlo de nuevo después.
El método update () no envía señales pre_ y post_, téngalo en cuenta.
pre_save
se usa antes de que se guarde la transacción.
post_save
se usa después de guardar la transacción.
Puede usar pre_save
por ejemplo si tiene un FileField
o un ImageField
y vea si el file
o la image
realmente existe.
Puede usar post_save
cuando tiene un post_save
y desea crear uno nuevo en el momento en que se crea un nuevo User
.