Django - signals. Simple examples to start
Asked Answered
A

5

33

I am new to Django and I'm not able to understand how to work with Django signals. Can anyone please explain "Django signals" with simple examples?

Thanks in advance.

Acetous answered 6/1, 2015 at 17:8 Comment(2)
Can you be more specific? The manual has a few examples already: docs.djangoproject.com/en/1.7/topics/signalsReiko
docs.djangoproject.com/en/4.0/topics/signals is the working linkIson
M
44

You can find very good content about django signals over Internet by doing very small research.

Here i will explain you very brief about Django signals.
What are Django signals?
Signals allow certain senders to notify a set of receivers that some action has taken place

Actions :

model's save() method is called.
django.db.models.signals.pre_save | post_save

model's delete() method is called.
django.db.models.signals.pre_delete | post_delete

ManyToManyField on a model is changed.
django.db.models.signals.m2m_changed

Django starts or finishes an HTTP request.
django.core.signals.request_started | request_finished

All signals are django.dispatch.Signal instances.

very basic example :

models.py

from django.db import models
from django.db.models import signals

def create_customer(sender, instance, created, **kwargs):
    print "Save is called"

class Customer(models.Model):
    name = models.CharField(max_length=16)
    description = models.CharField(max_length=32)

signals.post_save.connect(receiver=create_customer, sender=Customer)

Shell

In [1]: obj = Customer(name='foo', description='foo in detail')

In [2]: obj.save()
Save is called
Meistersinger answered 6/1, 2015 at 19:16 Comment(2)
A question - Why is signals.post_save.connect(receiver=create_customer, sender=Customer) called after the definition of Customer model? Also, why isn't that line indented? Won't that line execute even if class definition is not called? i.e if models.py is imported anywhere but no objects (class definitions, functions, etc.) from models.py are actually invoked.Tercentenary
Feels incomplete this answer.Adduce
T
20

Apart from the explanation given by Prashant, you can also use receiver decorator present in django.dispatch module.

e.g.

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

class Customer(models.Model):
    name = models.CharField(max_length=16)
    description = models.CharField(max_length=32)

@receiver(signals.pre_save, sender=Customer)
def create_customer(sender, instance, created, **kwargs):
    print "customer created"

For more information, refer to this link.

Telegenic answered 31/10, 2016 at 4:19 Comment(6)
In Prashant answer, used from signals.post_save and in your answer used from signals.pre_save, what's the difference between these?Persia
These two are two different signals, which gets emitted at different stages, during model persistence in db. post_save is after saving the model, pre_save is before saving the model.Telegenic
post_save usage is clear but what's usage of pre_save?Persia
This signal is triggered before saving the model..You can think of it as an interceptor, where you can execute something, before saving the model.Telegenic
is this means that in this situation call_back function always calls except at saving moment? or this means is when you are trying writing a filed in Django model before saving call_back function calls?Persia
but your example is not correct with pre_save, because it says "customer created"Theressathereto
G
0

In the signals.post_save.connect(receiver=create_customer, sender=Customer)... sender will always be the model which we are defining... or we can use the User as well in the sender.

Gastric answered 29/4, 2020 at 19:23 Comment(0)
G
0

Signals are used to perform any action on modification of a model instance. The signals are utilities that help us to connect events with actions. We can develop a function that will run when a signal calls it. In other words, Signals are used to perform some action on modification/creation of a particular entry in Database. For example, One would want to create a profile instance, as soon as a new user instance is created in Database

There are 3 types of signal.

  1. pre_save/post_save: This signal works before/after the method save().
  2. pre_delete/post_delete: This signal works before after delete a model’s instance (method delete()) this signal is thrown.
  3. pre_init/post_init: This signal is thrown before/after instantiating a model (init() method).

One of the example, if we want to create a profile of a user as soon as the user is created using post_save signal.

For code example, I found the Geeks for Geeks, which explains is very simple way, and easy to understand. https://www.geeksforgeeks.org/how-to-create-and-use-signals-in-django/

Gastric answered 15/8, 2021 at 15:34 Comment(0)
A
0

You can add signals to your models.py file

here is an example for adding an auto slug, if you use a SlugField:

this is the stuff you need to import

from django.utils.text import slugify
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save

Add the @receiver to the bottom of your class, included the def

If you add the def __str__(self): under the receiver, you will get an error

class Store(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=False, blank=True, null=True)

    def __str__(self):
        return self.name

@receiver(pre_save, sender=Store)
def store_pre_save(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = slugify(instance.name)

or you can use post_save

class Store(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=False, blank=True, null=True)

    def __str__(self):
        return self.name

@receiver(post_save, sender=Store)
def store_post_save(sender, instance, created, *args, **kwargs):
    if not instance.slug:
        instance.slug = slugify(instance.name)
        instance.save()

I found this example from this tutorial

Anacreon answered 15/9, 2021 at 5:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.