×
   ❮   
PYTHON FOR DJANGO DJANGO FOR BEGINNERS DJANGO SPECIFICS PAYMENT INTEGRATION Roadmap
     ❯   

DJANGO SIGNALS

Built-in Signals

Built-in Signals

Django comes with a variety of built-in signals that allow you to hook into different events during the lifecycle of models, forms, and request handling. These signals provide a powerful mechanism to respond to changes or actions across different components of your application, without modifying the core functionality of the components themselves.

Why Use Built-in Signals?

Using Django's built-in signals allows you to listen to important events like model saves, deletions, and request phases. By connecting receivers to these signals, you can automate tasks such as logging, notification systems, cleaning up data, or performing post-processing after a model action.

Common Built-in Signals in Django

Django provides several built-in signals for handling various stages of the model lifecycle and request/response cycle. Below are some of the most commonly used built-in signals:

  • pre_save: Triggered just before a model instance is saved.
  • post_save: Triggered immediately after a model instance is saved.
  • pre_delete: Triggered before a model instance is deleted.
  • post_delete: Triggered after a model instance is deleted.
  • m2m_changed: Triggered when a many-to-many relationship changes (e.g., adding or removing items).
  • request_started: Triggered when a request starts.
  • request_finished: Triggered when a request is finished and a response is sent back to the client.

Detailed Breakdown of Common Signals

pre_save

The pre_save signal is sent just before an instance of a model is saved. This is useful when you need to perform some actions or validations right before an object is saved to the database.


from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import MyModel

@receiver(pre_save, sender=MyModel)
def pre_save_handler(sender, instance, **kwargs):
    # Action to perform before the model is saved
    print(f'About to save: {instance}')

post_save

The post_save signal is triggered immediately after a model instance is saved. It’s commonly used for tasks that need to occur after the model has been written to the database, such as sending notifications or creating related records.


from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import MyModel

@receiver(post_save, sender=MyModel)
def post_save_handler(sender, instance, created, **kwargs):
    if created:
        print(f'New instance created: {instance}')
    else:
        print(f'Instance updated: {instance}')

pre_delete

The pre_delete signal is sent just before a model instance is deleted. This is helpful when you need to perform cleanup or take action before an object is removed from the database.


from django.db.models.signals import pre_delete
from django.dispatch import receiver
from .models import MyModel

@receiver(pre_delete, sender=MyModel)
def pre_delete_handler(sender, instance, **kwargs):
    # Action to perform before the model is deleted
    print(f'Preparing to delete: {instance}')

post_delete

The post_delete signal is triggered after a model instance has been deleted from the database. This is often used to perform tasks like cleaning up associated data or files.


from django.db.models.signals import post_delete
from django.dispatch import receiver
from .models import MyModel

@receiver(post_delete, sender=MyModel)
def post_delete_handler(sender, instance, **kwargs):
    # Action to perform after the model is deleted
    print(f'Instance deleted: {instance}')

m2m_changed

The m2m_changed signal is sent whenever there are changes to a many-to-many relationship in Django. For instance, this signal is triggered when items are added, removed, or cleared from a many-to-many field.


from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from .models import MyModel

@receiver(m2m_changed, sender=MyModel.some_m2m_field.through)
def m2m_changed_handler(sender, instance, action, **kwargs):
    if action == 'post_add':
        print(f'Items added to the relationship: {instance}')

request_started

The request_started signal is triggered whenever a new HTTP request is received by Django. This signal can be useful for logging request activity or performing actions before request processing begins.


from django.core.signals import request_started
from django.dispatch import receiver

@receiver(request_started)
def request_started_handler(sender, **kwargs):
    print('A new request has started!')

request_finished

The request_finished signal is sent when Django finishes processing a request and sends the response back to the client. This can be useful for logging response times or clearing resources after a request has been handled.


from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def request_finished_handler(sender, **kwargs):
    print('The request has finished processing.')

Conclusion

Django’s built-in signals provide a powerful way to respond to specific events in your application without the need for tight coupling between components. Whether you’re working with model lifecycle signals like pre_save and post_save or request-related signals like request_started and request_finished, understanding how to use these signals can help you build more efficient and modular applications.

In the next sections, we will cover creating custom signals and more advanced use cases for signals in Django.


References


Django-tutorial.dev is dedicated to providing beginner-friendly tutorials on Django development. Examples are simplified to enhance readability and ease of learning. Tutorials, references, and examples are continuously reviewed to ensure accuracy, but we cannot guarantee complete correctness of all content. By using Django-tutorial.dev, you agree to have read and accepted our terms of use , cookie policy and privacy policy.

© 2024 Nischal Lamichhane. All Rights Reserved.
Django-tutorial.dev is styled using Bootstrap 5.
And W3.CSS.