Using Signals in Django
Registering signals
In this video, we are going to learn how to use signals in django and fix the issue of profile image update.
At first, create a signals.py file in the user app.
Then, open your apps.py file. In this file, we have to register our receivers which we will write in the signals.py file.
# Create a function named ready.
def ready(self):
# In this function, import the content of signals file
from . import signals
# Then return the super method of ready
return super().ready()
Creating the receivers
In this signals.py file, lets import some important modules and functions.
# At first import the os module to perform the delete operation on the profile image file.
import os
# Then import the receiver to create a receiver
from django.dispatch import receiver
# Then import the models
from django.db import models
# Then import the get_user_model
from django.contrib.auth import get_user_model
# And create a user model instance
User = get_user_model()
# Now, lets create a receiver.
# This receiver takes two argument, the first argument is the name of the signal and second argument is the name of the model that sends that signal.
@receiver(models.signals.pre_save, sender=User)
# Now create a function. This function have 3 parameters, sender, instance and **kwargs.
def auto_delete_file_on_change(sender, instance, **kwargs):
# Sender is basically the name of the model that is sending the signal. In our case, it is User model.
# Instance will store the new value which the user wants to update
# Now, at first, what we will do, we will check the primary key of the user instance.
if not instance.pk:
# If the pk is None then we will return False
return False
# After that, we have to grab the old photo of the user instance
try:
old_photo = User.objects.get(pk=instance.pk).photo
except User.DoesNotExist:
return False
# The new photo will be accessed via instance.photo
new_photo = instance.photo
# Now, we will check whether the old photo is not None and new_photo is not equal to old_photo
if old_photo is not None and new_photo != old_photo:
# Here, we will delete the old_photo using os module
if os.path.isfile(old_photo.path):
os.remove(old_photo.path)
[Run the development server and see the changes]
[Commit the changes and push it in the remote repository.]