Django signals are a way that certain parts of a Django app can be notified when user actions or system events have taken place. You can think of them as event-driven programming for your Django applications: an action takes place and a signal is sent and received by whoever chooses to listen.
Django provides several built-in signals that allow certain senders to notify a set of receivers whenever specific actions have taken place. They’re used in various core Django functionalities and are also available for you to use in your own applications.
To use Django signals, there are two main steps involved – you need to define your signal handlers and then connect your signals to these handlers. A signal handler is a function or a method where you define what to take place once a certain signal is received.
Take the Django’s built-in `pre_save` signal for example. This signal is sent just before a model’s `save()` method is called. You might want to perform certain actions, like updating some fields of the model instance, each time this signal is sent.
Firstly, you would define a signal handler function. This function must accept two arguments: ‘sender’ (the model class that the signal was sent by) and ‘instance’ (the actual instance of the model that’s being saved):
```
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel
@receiver(pre_save, sender=MyModel)
def my_signal_handler(sender, instance, **kwargs):
instance.some_field = ‘Some Value‘
```
This signals that every time an instance of `MyModel` is about to be saved, the `my_signal_handler` function will update `some_field` of the instance to ‘Some Value’.
The `@receiver` decorator is a convenient way for linking signals to receivers. It’s used to specify the signal to listen to and the sender from where the signals will be sent. It’s important to ensure that Django is aware of your signal handlers. Usually, you’d put the signals in your models.py file. However, if your signal handlers are in a different file, remember to import that file in your AppConfig’s ready method.
This scratch at the surface of Django signals. There is a lot more depth to explore – different types of signals (not just model signals), the order in which multiple receivers are called, handling signal sending failures, and much more.
Remember that while signals can be powerful, they can also make your code hard to understand and debug since they can lead to side effects that are not easily traceable. As the Django documentation cautions, they’re not always the best tool for the job.
Sources:
1. Django documentation: Models – https://docs.djangoproject.com/en/3.2/topics/signals/
2. Django documentation: Signals – https://docs.djangoproject.com/en/3.2/topics/signals/
3. Learn Django Signals – https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html
4. Django Signals: An Extremely Simplified Explanation for Beginners https://djangocentral.com/django-signals/