Learn Django Signals | The Quickest and Easiest Way for Beginners
In this post, you are going to learn about Django Signals using real-life examples. And by the end of this tutorial, you have a good understanding of what Django Signals are and their applications.
Table of Contents
While working with large multiple tables were each table share one-to-one or many-to-many which are inter-connected
to each other as a programmer change a simple way must by manually updating dependent fields. But this can be a tidies task to achieve.
For Example:
Let us consider two tables user, profile the user share a one-to-one relationship with the profile table which has date_of_birth, age, address as fields.
While updating or creating users we must also create/update profiles and this has to be done everywhere were user details get updated.
Hence insisted on rewriting the same code. We can make use of Django signals.
Model Signals
Django Signals trigger event application whenever the model gets created, updated, or deleted in this way we can manage logic by minimum code.
We have a blogs table and we’ll be using this as an example below.
Create Model models.py and migrate it to the database
class BlogModel(models.Model): BLOG_STATUS = ( ('PUBLISH', 'Publish'), ('DRAFT', 'Draft'), ) blog_id = models.AutoField(primary_key=True) user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='blogs' ) title = models.CharField(max_length=255) content = models.TextField(blank=True, null=True) status = models.CharField(max_length=7, choices=BLOG_STATUS) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta(): db_table = 'blogs' verbose_name = 'Blog' verbose_name_plural = 'Blogs' def __str__(self): return self.title
Django provides with different Types of Signals. But in this post, we’ll be discussing types of Model Signals.
pre_init signal
This signal is called before the model __init__()
is instantiated.
Arguments
- sender: Class Name of Model.
- args: These are a list of arguments to be passed to
__init__()
. - kwargs : This is a dictionary type.
Example
@receiver(pre_init, sender=BlogModel) def blog_pre_init_signal(sender, *args, **kwargs): print("blog_pre_init_signal() called") #SHELL >>> Blog=BlogModel() blog_pre_init_signal() called
post_init signal
This signal is called after model __init__()
is instantiated.
Example
@receiver(post_init, sender=BlogModel) def blog_post_init_signal(sender, *args, **kwargs): print("blog_post_init_signal() called") #SHELL >>> blog = BlogModel() blog_pre_init_signal() called blog_post_init_signal() called
As in above example first it calls blog_pre_init_signal() called and after that blog_post_init_signal() called.
pre_save signal
This signal gets called before saving or updating the instance
post_save signal
This signal gets called after saving instance. The post_save
has an argument created=true
when a new instance is saved and while updating created=false
.
Example
@receiver(pre_save, sender=BlogModel) def blog_pre_save_signal(sender, *args, **kwargs): print('---------------------------------\n') print('blog_pre_save_signal() called') print('sender : {}\n'.format(sender)) print('args : {}\n'.format(args)) print('kwargs : {}\n'.format(kwargs)) print('---------------------------------\n') @receiver(post_save, sender=BlogModel) def blog_post_save_signal(sender, *args, **kwargs): print('---------------------------------\n') print('blog_post_save_signal() called') print('sender : {}\n'.format(sender)) print('args : {}\n'.format(args)) print('kwargs : {}\n'.format(kwargs)) print('---------------------------------\n') #SHELL >>> user = User.objects.get(pk=1) >>> print(user) root >>> create_blog_kwarg = {"user":user,"title":"New Blog created","content":"Blog sample description","status":"PUBLISH"} >>> blog=BlogModel.objects.create(**create_blog_kwarg) blog_pre_init_signal() called blog_post_init_signal() called --------------------------------- blog_pre_save_signal() called sender : <class 'blogs.models.BlogModel'> args : () kwargs : {'signal': <django.db.models.signals.ModelSignal object at 0x7fb35bf62ba8>, 'using': 'default', 'update_fields': None, 'instance': <BlogModel: New Blog created>, 'raw': False} --------------------------------- --------------------------------- blog_post_save_signal() called sender : <class 'blogs.models.BlogModel'> args : () kwargs : {'signal': <django.db.models.signals.ModelSignal object at 0x7fb35bf62c50>, 'update_fields': None, 'created': True, 'raw': False, 'instance': <BlogModel: New Blog created>, 'using': 'default'} ---------------------------------
pre_delete signal
This signal is called before the deleting the model instance.
post_delete signal
This signal is called after the deleting the model instance.
Example
@receiver(pre_delete, sender=BlogModel) def blog_pre_delete_signal(sender, *args, **kwargs): print('---------------------------------\n') print('blog_pre_delete_signal() called') print('sender : {}\n'.format(sender)) print('args : {}\n'.format(args)) print('kwargs : {}\n'.format(kwargs)) print('---------------------------------\n') @receiver(post_delete, sender=BlogModel) def blog_post_delete_signal(sender, *args, **kwargs): print('---------------------------------\n') print('blog_post_delete_signal() called') print('sender : {}\n'.format(sender)) print('args : {}\n'.format(args)) print('kwargs : {}\n'.format(kwargs)) print('---------------------------------\n') #SHELL >>> blog = BlogModel.objects.get(pk=160) blog_pre_init_signal() called kwargs : {'kwargs': {}, 'args': (160, 1, 'signal 1 ', 'Signal Changed', 'PUBLISH', datetime.datetime(2019, 5, 16, 10, 5, 48, 242734, tzinfo=<UTC>), datetime.datetime(2019, 5, 27, 6, 51, 3, 915106, tzinfo=<UTC>)), 'signal': <django.db.models.signals.ModelSignal object at 0x7fca0a43b908> } args : () blog_post_init_signal() called >>> blog.delete() --------------------------------- blog_pre_delete_signal() called sender : <class 'blogs.models.BlogModel'> args : () kwargs : {'using': 'default', 'instance': <BlogModel: signal 1 >, 'signal': <django.db.models.signals.ModelSignal object at 0x7fca0a43bcc0> } --------------------------------- --------------------------------- blog_post_delete_signal() called sender : <class 'blogs.models.BlogModel'> args : () kwargs : {'using': 'default', 'instance': <BlogModel: signal 1 >, 'signal': <django.db.models.signals.ModelSignal object at 0x7fca0a43bd68> } --------------------------------- (1, {'blogs.BlogModel': 1, 'blogs.BlogFilesModel': 0})
Conclusion
We have come to the final part of this post. Till now we have discussed types of model signals such as pre_init, post_init, pre_save, post_save, pre_delete, post_delete.
If you like this post then don’t forget to share and for any queries comment below.
Related Posts
- How to Send Emails and Attachments using Django
- Python Django – Multiple Files Validation and Uploads




