usar trigger señales notificaciones como before django

trigger - señales django



Consolidando múltiples señales post_save con un receptor (4)

Puede omitir el nombre de model_name y se conectará a todos los modelos post_save. Luego puede filtrar si está en el modelo correcto en el controlador:

post_save.connect(foo) def foo(sender, **kwargs): if sender not in [FooModel, BarModel]: return ... actual code ...

o puede filtrar según el campo en el modelo:

def foo(sender, **kwargs): if not getattr(sender, ''process_by_foo'', False): return ... actual code ...

Así que leí el código fuente de Django (post 1.5) que ahora puede registrar múltiples señales múltiples en una función de receptor:

def receiver(signal, **kwargs): """ A decorator for connecting receivers to signals. Used by passing in the signal (or list of signals) and keyword arguments to connect:: @receiver(post_save, sender=MyModel) def signal_receiver(sender, **kwargs): ... @receiver([post_save, post_delete], sender=MyModel) def signals_receiver(sender, **kwargs): ... """ ... implementation code...

Sin embargo, quiero registrar múltiples señales post_save de diferentes remitentes a la misma función. En este momento, acabo de llamar

post_save.connect(fn_name, model_name)

Para cada modelo que tengo. ¿Hay una mejor manera de hacer esto con la nueva capacidad de decorador Django 1.5 @receiver?


Puedes usar eso usando el decorador @receiver:

@receiver(post_save, sender=Model1) @receiver(post_save, sender=Model2) @receiver(post_save, sender=Model3) def my_signal_handle(sender , **kwargs) # some code here


Según la documentación de Django sobre los receptores , los receptores por defecto no necesitan estar conectados a un remitente específico . Entonces, lo que estás describiendo es la funcionalidad predeterminada de Django.

En otras palabras, para hacer esto usando el decorador @receiver simplemente no especificas un remitente en el decorador. Por ejemplo:

@receiver(post_save) # instead of @receiver(post_save, sender=Rebel) def set_winner(sender, instance=None, created=False, **kwargs): list_of_models = (''Rebel'', ''Stormtrooper'', ''Battleground'') if sender.__name__ in list_of_models: # this is the dynamic part you want if created: # only run when object is first created ... set the winner ...

Esto supone modelos que parecen:

class Rebel(models.Model): ... class Stormtrooper(models.Model): ... class Battleground(models.Model): ...


def receiver_with_multiple_senders(signal, senders, **kwargs): """ Based on django.dispatch.dispatcher.receiver Allows multiple senders so we can avoid using a stack of regular receiver decorators with one sender each. """ def decorator(receiver_func): for sender in senders: if isinstance(signal, (list, tuple)): for s in signal: s.connect(receiver_func, sender=sender, **kwargs) else: signal.connect(receiver_func, sender=sender, **kwargs) return receiver_func return decorator