Signals in Django

- Andrés Cruz

En español
Signals in Django

Este material forma parte de mi curso y libro completo; puedes adquirirlos desde el apartado de libros y/o cursos Curso y libro desarrollo web con Django 5 y Python 3 + integración con Vue 3, Bootstrap y Alpine.js.

Django includes a package to manage the application's Signals, with which it is possible that the application can receive notifications when certain actions occur in the application, such as creating a post, registering a user, etc, when any of these actions happen, we can trigger this signal to execute a function that performs some action such as recording a log, sending an email, among others.

Signals are nothing more than configurable events or messengers that report important events in our application, they are a form of communication between different parts of the application. In this chapter, we'll explain what Signals are, how they work, and how you can take advantage of them to keep your code organized and efficient.

Signals are a form of communication between different parts of your application. With signals, it is possible to notify a set of receivers that something has happened.

As an example, assuming we have a blog and you want to send an email every time someone registers, we can use Signals in Django, the event is the registration of the event that triggers a signal that is connected to a function that is the one that send the email; this action can be any other operation such as sending a notification or another custom task.

The use of signs is very easy, we just have to create a function that must be executed when the event happens, this function is the receive or the one that receives, and we specify it using the from django.dispatch import receiver decorator which, we establish two parameters, the signal type and the model.

Signal types

We have different types of signals, you can use all of them to perform personalized actions before/after performing the corresponding actions and we can classify them into five types:

  1. For the models
  2. Migrations
  3. Requests/responses
  4. Evidence
  5. Database

Model Signals

Signals related to models:

  • pre_init: Triggered just before a new instance of the associated model is created.
  • post_init: Triggered after a new instance of a model has been created.
  • pre_save: Activated before saving an instance of a model in the database.
  • post_save: Executed after an instance of a model has been saved to the database. It is useful for performing post-save actions, such as sending notifications or updating related models.
  • pre_delete: Triggered before deleting an instance of a model. You can use it to perform pre-deletion actions, such as freeing resources or related records.
  • post_delete: Executed after deleting an instance of a model. You can use it to perform post-deletion tasks, such as freeing resources or related logs.
  • m2m_changed: This signal is triggered when many-to-many relationships are changed.
  • class_prepared: Fired when a model class is fully prepared and ready for use. You can use it to make additional configurations in model classes.

Migrations Signals

Signals related to migrations:

  • pre_migrate: Executed before applying migrations to the database.
  • post_migrate: Triggered after migrations are applied to the database. You can use it to perform post-migration actions, such as loading initial data or updating schemas.

Request/Response Signals

Signals related to HTTP requests and responses:

  • request_started: Fired at the start of an HTTP request.
  • request_finished: Executed upon completion of an HTTP request.
  • got_request_exception: Triggered when an exception occurs during the processing of a request. Useful for handling errors and recording the exception in a log.

Test Signals

Signals related to unit tests:

  1. setting_changed: This signal is sent when the value of a setting is changed. Useful for handling changes to application configurations during testing.
  2. template_rendered: Sent when the test system renders a template.

Database Wrappers

Signals related to database connections:

  1. connection_created: Triggered when a connection to a database is established.

When receiving these signals it has specific parameters that you can explore in the official documentation:

 

https://docs.djangoproject.com/en/dev/ref/signals/

Implement a Signal

The first thing we must do is define a Signal, for this we use a function that is activated when a specific event occurs, for example, the creation of an alert:

channels/alert/signals.py

 

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

@receiver(post_save, sender=Alert)
def save_user_profile(sender, instance, **kwargs):
    print('Alert Created')

This function will act as a receiver of the signal, that is, it will be executed when the corresponding signal is executed, in this example, the corresponding signal is the creation (post_save) of an alert, it will display a message through the console, but, the task to perform can be any other operation such as sending an email or other database operations.

Register Signals

In the apps.py file of your application, we must register the signals.py file in the ready() method:

channels/alert/apps.py

from django.apps import AppConfig

class AlertConfig(AppConfig):
    name = 'alert'

    def ready(self):
        import alert.signals

In this example method, we create an alert:

channels/alert/views.py

from django.contrib.auth.decorators import login_required
from django.http import HttpResponse

from .models import Alert

@login_required
def create(request):
    alert = Alert()
    alert.content = 'Test'
    alert.user = request.user
    alert.save()
    return HttpResponse('Response')

And we create the path of the previous view:

channels/alert/urls.py

urlpatterns = path('dashboard/create',views.create),

Now, every time we create an alert, the previous signal will be automatically executed, and this is an important factor, every time an alert is created, for example, from Django Channels, or through the consumer that we created in the previous section, the previous signal will be executed, as we mentioned previously, the signal is nothing more than a function associated with an event except that the signal is executed automatically when the event occurs.

 

Official documentation:

 

https://docs.djangoproject.com/en/dev/topics/signals/

https://docs.djangoproject.com/en/dev/ref/signals/

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.