Signals
Usar signals debe ser nuestra ultima opción. Los signals son una herramienta util para pogramar acciones, sin embargo es muy facil volver el codigo en algo similar a una caja negra para el programador, ya que al usar los signals de manera excesiva, esto puede causar una gran cantidad de comportamientos no esperados, no deseados, o indeseados, por ejemplo, imagina que debes actualizar el estado de un cliente cuando se crea una factura, entonces realizas el siguiente codigo:
# Guarda cambio a cliente
cliente.pagado = True
cliente.save()
# Guarda factura
factura.save()
pero al revisar el estado del cliente, notas que el cambio no se realizo en el cliente, porque paso esto?
Es porque hay un signal que escucha cuando se realiza un save en el modelo Factura. Algo como esto:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Cliente)
def post_save_client(sender, created, instance, **kwargs):
cliente = instance
cliente.pagado = False
cliente.save()
Esto causa que se sobreescriba tu cambio sin saber que existe dicho signal, esto empeora cuando realizas cambio asincronos en task u otras herramientas, ahora imagina encadenar multiples signals, puedes llegar a encadenar multiples eventos, que incluso pueden crear bucles. Incluyendo otros problemas que pueden ocurrir es la perdida de señales, por motivos relacionados a concurrencia, o multiples alteraciones simultaneas.