Django Signals
Tags: django, python, webdev
Published: 2022-04-11 09:53:59

Hi guys here i am with an other post about django signals
first of all why do we need django signals. django signals can become useful when we try to develop some event based functonality in our backend

in django we have two entities one is sender and other is receiver the sender will send a signal on any particular event and all the receivers who are listening for that event are notified with the signal and perform certain kind of actions


## Signals based on Djano Models
lets see few examples by using django's inbuild signals

let's define few models in django's models.py
```python
# models.py

from django.db import models
from django.contrib.auth.models import User
import datetime

# Create your models here.
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profile_url = models.URLField()
    mobile = models.CharField(max_length=20, default='999-999-9999')
    funds = models.FloatField(default=2000)

    def __str__(self):
        return "[PROFILE]:" + self.user.username


class Log(models.Model):
    timestamp = models.DateTimeField(default=datetime.datetime.now)
    message = models.TextField()

    def __str__(self):
        return self.message
```

here we have defined two models **Profile** which extends the inbuilt **User** model by **models.OneToOneField** and another is **Log** model which is simply used to store the Log messages in database


now lets define a reveiver which uses **post_save** signal which is triggered after a particular model is saved into database

```python
# models.py

# .... models defined above

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


# triggred when User object is created
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(
            user=instance
        )

# triggred when User object is saved
@receiver(post_save, sender=User)
def log_user_saved(sender, instance, **kwargs):
    Log.objects.create(
        message=f"user {instance.username} is saved"
    )

# triggred when Profile object is saved
@receiver(post_save, sender=Profile)
def log_profile_saved(sender, instance, **kwargs):
    Log.objects.create(
        message=f"profile {instance} is saved"
    )
```

as you can see above we have created 3 receiver functions lets see each one of them

**create_profile** this receiver is triggred when the post_save signal on User model is generated i.e after the user model has been saved to the database the post_save signal is generated by User model and the create_profile receiver is triggred

in create_profile we are creating Profile for the User we can verifiy this by going to django admin and creating a user

**Creating User**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8qkox85xt2f0p8hg6ub.png)

**User Saved**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrqcpyvsh72zvixku1en.png)

**Profile Created**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol9m368qg79dx8ixprm2.png)

as we can see in the above image the profile is created automatically for the user with the help of post_save signal


similarly if we go to the Log model we can see the logs created for each signal


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkd4o1veuqk4tzifokc3.png)

in the above image we can see that Log objects are created when a signal on User and Profile are triggered


similar to post_save we have signals like **pre_save**, **pre_delete**, **post_delete**, **pre_init**,
**post_init**, **m2m_changed**


## The receiver functions for various signals

**pre_init**

```python
receiver_function(sender, *args, **kwargs)
```

**post_init**

```python
receiver_function(sender, instance)
```

**pre_save**

```python
receiver_function(sender, instance, raw, using, update_fields)
```

**post_save**

```python
receiver_function(sender, instance, created, raw, using, update_fields)
```

**pre_delete**

```python
receiver_function(sender, instance, using)
```

**post_delete**

```python
receiver_function(sender, instance, using)
```

**m2m_changed**

```python
receiver_function(sender, instance, action, reverse, model, pk_set, using)
```