Django Model Signals makes it easier to keep business logic in your Django models by allowing them to become transceivers of their own signals, including bulk signals.
pip install django-model-signals
Add the django_model_signals
app to your INSTALLED_APPS
:
INSTALLED_APPS = [
# ...
'django_model_signals',
]
- Add a
ModelSignalsMeta
inner class to your Django model and specify which signals you want to connect. - To enable the
pre_bulk_save
andpost_bulk_save
signals, add theModelSignalsManager
to your Django model'sobjects
property. - To enable the
pre_full_clean
,post_full_clean
andpost_full_clean_error
signals, inherit from theFullCleanSignalsMixin
in your Django model. - To enable the
post_save_error
signal, inherit from thePostSaveErrorSignalMixin
in your Django model. - Implement the receiver methods for the connected signals in your Django model.
from django.db.models import Model
from django_model_signals.manager import ModelSignalsManager
from django_model_signals.models import (
FullCleanSignalsMixin,
PostSaveErrorSignalMixin
)
class MyModel(
FullCleanSignalsMixin,
PostSaveErrorSignalMixin,
Model
):
@classmethod
def pre_init(cls, **kwargs):
pass
def post_init(self, **kwargs):
pass
def pre_full_clean(self, **kwargs):
pass
def post_full_clean(self, **kwargs):
pass
def post_full_clean_error(self, **kwargs):
raise kwargs['error']
def pre_save(self, **kwargs):
pass
def post_save(self, **kwargs):
pass
def post_save_error(self, **kwargs):
raise kwargs['error']
def pre_delete(self, **kwargs):
pass
def post_delete(self, **kwargs):
pass
def m2m_changed(self, **kwargs):
pass
@classmethod
def pre_bulk_save(cls, **kwargs):
pass
@classmethod
def post_bulk_save(cls, **kwargs):
pass
objects = ModelSignalsManager()
class ModelSignalsMeta:
signals = [
'pre_init',
'post_init',
'pre_full_clean',
'post_full_clean',
'post_full_clean_error',
'pre_save',
'post_save',
'post_save_error',
'pre_delete',
'post_delete',
'm2m_changed',
'pre_bulk_save',
'post_bulk_save'
]
- The following actions are supported for triggering the implemented signals:
- Creating or loading an model instance from the database will trigger the
pre_init
andpost_init
signals. - Calling
Model.full_clean
will trigger thepre_full_clean
andpost_full_clean
signals. - An error during
Model.full_clean
will trigger thepost_full_clean_error
signal. - Calling
Model.save
will trigger thepre_save
andpost_save
signals. - An error during
Model.save
will trigger thepost_save_error
signal. - Calling
Model.delete
will trigger thepre_delete
andpost_delete
signals. - Calling
Model.objects.create
will trigger thepre_save
andpost_save
signals. - Calling
Model.objects.get_or_create
will trigger thepre_save
andpost_save
signals. - Calling
Model.objects.update_or_create
will trigger thepre_save
andpost_save
signals. - Calling
Model.objects.bulk_create
will trigger thepre_bulk_save
andpost_bulk_save
signals. - Calling
Model.objects.bulk_update
will trigger thepre_bulk_save
andpost_bulk_save
signals. - Calling
QuerySet.delete
will trigger thepre_delete
andpost_delete
signals.
- Creating or loading an model instance from the database will trigger the
- To implement the
pre_full_clean
andpost_full_clean
,post_full_clean_error
andpost_save_errors
signals, this library overrides thefull_clean
andsave
methods of Django models and calls the original method in a backwards compatible way. However, make sure the order of the classes inherited from is the same as the above example to ensure the proper method resolution order. - The
post_full_clean_error
andpost_save_error
signals are not actually called as signals, but the receiver methods are called directly. This allows you to suppress, change or re-raise the error.
- Django: https://www.djangoproject.com/