Signal support

Models with hooks for signals (a-la django) are provided inplayhouse.signals. To use the signals, you will need all of your project’smodels to be a subclass of playhouse.signals.Model, which overrides thenecessary methods to provide support for the various signals.

  1. from playhouse.signals import Model, post_save
  2.  
  3.  
  4. class MyModel(Model):
  5. data = IntegerField()
  6.  
  7. @post_save(sender=MyModel)
  8. def on_save_handler(model_class, instance, created):
  9. put_data_in_cache(instance.data)

Warning

For what I hope are obvious reasons, Peewee signals do not work when youuse the Model.insert(), Model.update(), orModel.delete() methods. These methods generate queries thatexecute beyond the scope of the ORM, and the ORM does not know about whichmodel instances might or might not be affected when the query executes.

Signals work by hooking into the higher-level peewee APIs likeModel.save() and Model.delete_instance(), where theaffected model instance is known ahead of time.

The following signals are provided:

  • pre_save
  • Called immediately before an object is saved to the database. Provides anadditional keyword argument created, indicating whether the model is beingsaved for the first time or updated.
  • post_save
  • Called immediately after an object is saved to the database. Provides anadditional keyword argument created, indicating whether the model is beingsaved for the first time or updated.
  • pre_delete
  • Called immediately before an object is deleted from the database when Model.delete_instance()is used.
  • post_delete
  • Called immediately after an object is deleted from the database when Model.delete_instance()is used.
  • pre_init
  • Called when a model class is first instantiated

Connecting handlers

Whenever a signal is dispatched, it will call any handlers that have beenregistered. This allows totally separate code to respond to events like modelsave and delete.

The Signal class provides a connect() method,which takes a callback function and two optional parameters for “sender” and“name”. If specified, the “sender” parameter should be a single model classand allows your callback to only receive signals from that one model class.The “name” parameter is used as a convenient alias in the event you wish tounregister your signal handler.

Example usage:

  1. from playhouse.signals import *
  2.  
  3. def post_save_handler(sender, instance, created):
  4. print '%s was just saved' % instance
  5.  
  6. # our handler will only be called when we save instances of SomeModel
  7. post_save.connect(post_save_handler, sender=SomeModel)

All signal handlers accept as their first two arguments sender andinstance, where sender is the model class and instance is theactual model being acted upon.

If you’d like, you can also use a decorator to connect signal handlers. Thisis functionally equivalent to the above example:

  1. @post_save(sender=SomeModel)def post_save_handler(sender, instance, created): print '%s was just saved' % instance

Signal API

  • class Signal
  • Stores a list of receivers (callbacks) and calls them when the “send”method is invoked.

    • connect(receiver[, sender=None[, name=None]])

Parameters:

  1. - **receiver** (_callable_) a callable that takes at least two parameters,a sender”, which is the Model subclass that triggered the signal, andan instance”, which is the actual model instance.
  2. - **sender** ([_Model_]($91d5d4e449d7d4b4.md#Model)) – if specified, only instances of this model class willtrigger the receiver callback.
  3. - **name** (_string_) a short alias

Add the receiver to the internal list of receivers, which will be calledwhenever the signal is sent.

  1. from playhouse.signals import post_save
  2. from project.handlers import cache_buster
  3.  
  4. post_save.connect(cache_buster, name='project.cache_buster')
  • disconnect([receiver=None[, name=None]])

Parameters:

  1. - **receiver** (_callable_) the callback to disconnect
  2. - **name** (_string_) a short alias

Disconnect the given receiver (or the receiver with the given name alias)so that it no longer is called. Either the receiver or the name must beprovided.

  1. post_save.disconnect(name='project.cache_buster')
  • send(instance, *args, **kwargs)

Parameters:instance – a model instance

Iterates over the receivers and will call them in the order in whichthey were connected. If the receiver specified a sender, it will onlybe called if the instance is an instance of the sender.