Signal support

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

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

Warning

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

Signals work by hooking into the higher-level peewee APIs like Model.save() and Model.delete_instance(), where the affected 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 an additional keyword argument created, indicating whether the model is being saved for the first time or updated.

post_save

Called immediately after an object is saved to the database. Provides an additional keyword argument created, indicating whether the model is being saved 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 been registered. This allows totally separate code to respond to events like model save 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 class and 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 to unregister your signal handler.

Example usage:

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

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

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

  1. @post_save(sender=SomeModel)
  2. def post_save_handler(sender, instance, created):
  3. 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:
    • receiver (callable) – a callable that takes at least two parameters, a “sender”, which is the Model subclass that triggered the signal, and an “instance”, which is the actual model instance.
    • sender (Model) – if specified, only instances of this model class will trigger the receiver callback.
    • name (string) – a short alias

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

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

    Parameters:
    • receiver (callable) – the callback to disconnect
    • 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 be provided.

    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 which they were connected. If the receiver specified a sender, it will only be called if the instance is an instance of the sender.