What are Django Signals?
Django signals help separate applications in a project to communicate. In that, when a specific event occurs it triggers the occurrence of another event.
When to use signals...
Django signals are just like the green light in a traffic light, if the green light comes on it triggers the movement of cars.
A common use case of Django signals is when you have a User Model that has a One to One relationship with a Profile Model. Here we aim to create a Profile instance anytime a user object is created or update an existing profile instance when the user object is updated. This is where signals come to the rescue. Signals listen to the post-event of the User Model that is after the .save() method is called. Once the .save() method is called a post_save signal is sent, which triggers a receiver function that creates the profile instance or update the existing instance.
Let's write some code ...
Before we move on, we've noticed that there are senders and receivers in signals...
Senders must either be a Python object or None which will receive signals from any sender
Receivers must either be a function or instance method
users/models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length = 200)
email = models.EmailField()
#another application models
profile/models.py
from django.db import models
class Profile(models.Model):
user= models.OnetoOneField(User, on_delete = models.CASCADE)
email = models.EmailField()
Our models are all set, so let's use the Django built-in signals specifically the model signals which is post_save signal
profile/signals.py
from .models import Profile
from base.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender = User)
def create_profile(sender, instance, created, *args, **kwargs):
if created:
Profile.objects.create(user = instance)
#post_save.connect(create_profile, sender = User)
To connect the sender and receiver you can either use the @receiver decorator or the .connect() method of the Signal instance.
So what will happen here ...
Once a user object is saved a profile instance is created where the user field is populated with the user instance created.
Our last bit will be configurations of the signals.py file...
Inside our apps.py we will create a ready() function where we will import our signals.py file
profile/apps.py
from django.apps import AppConfig
class ProfileConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "profile"
def ready(self):
import profile.signals
In addition,
In the settings.py under the INSTALLED_APPS make sure to register your app like this "profile.apps.ProfileConfig"
, if registered by only indicating the apps name i.e "profile"
make sure to write the following code in __init__.py
file of the package where the signals.py file is located.
profile/__init__.py
default_app_config = 'profile.apps.ProfileConfig'
Check out the Django docs to learn more built-in Django signals.
QUOTE OF TODAY by William James
If you can change your mind, you can change your life.
Thanks for reading 😄
Top comments (0)