Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending and receiving signals in django models

I am using django 2.0.8 and Python 3.5. I want to be able to send and receive custom signals when an object is saved to the database.

I have followed the Django documentation on listening to signals and also the core signals bundled with Django - however, I am unable to get my example to work.

This is what I have so far:

myapp/models.py

from django.db import models
import django.dispatch

my_signal = django.dispatch.Signal(providing_args=["name"])

class Foo(models.Model):
    name = models.CharField(max_length=16)

def save(self, *args, **kwargs):
    try:
        # Call the "real" save() method.
        super().save(*args, **kwargs)  

        # Fire off signal         
        my_signal.send(sender=self.__class__, name=self.name)

    except Exception as e:
        print ('Exception:', e)
        #pass

myapp/signals.py

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


@receiver(post_save, sender=Foo)
def foo_handler(sender, **kwargs):
    print('Foo Signal Recieved!')
    print(kwargs)

myapp/app.py

class MyappConfig(AppConfig):
    name = 'myapp'
    label = 'myapp'

    def ready(self):
        import myapp.signals

Sample usage

from myapp.models import Foo

foo = Foo(name='Homer Simpson')
foo.save() # Object is saved, but event is not fired!

Can anyone explain why the signal is not being fired?

like image 447
Homunculus Reticulli Avatar asked Aug 31 '18 10:08

Homunculus Reticulli


People also ask

What are the signals in Django?

Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.

How do you write signals in Django?

There are 3 types of signal. pre_save/post_save: This signal works before/after the method save(). pre_delete/post_delete: This signal works before after delete a model's instance (method delete()) this signal is thrown.

Where is Pre_save signal in Django?

pre_save. This is sent at the beginning of a model's save() method. Arguments sent with this signal: sender.

What is Post_save in Django?

In the example above, save_profile is our receiver function, User is the sender and post_save is the signal. You can read it as: Everytime when a User instance finalize the execution of its save method, the save_profile function will be executed. If you supress the sender argument like this: post_save.


1 Answers

It seems you need two features supplied by Django. signal and contenttypes.

So read the doc first

The model Activity is related to contenttypes,seems you miss object_id Field, which indicate which model instance is being crud.

For every crud action, An Activity instance is being created.This part is just the code written in signal.py

signal: signal have to connect each concrete model. Fortunately,See the source code of decorator receiver.

We have a signal list [post_save,post_delete] and a model list (FoodooChile, FooBarChile) to connect .

In post_save,argument created indicate the action is create or update.

At last, Usually we import the signal file in urls.py, maybe not the best practice.


It is also related to your settings.py. use 'myapp.apps.MyappConfig' replace myapp in settings.py,or define default_app_config = 'myapp.apps.MyappConfig' in myapp/__init__.py. The link above in comments describe this in detail

like image 186
newlife Avatar answered Oct 11 '22 23:10

newlife