1

I have a model that I want to implement a signal's post_save on. Here's my model:

    class Answer(models.Model):
        question = models.ForeignKey(
            Question,
            related_name='answers_list',
            on_delete=models.CASCADE
        )

        answer = models.CharField(max_length=500)
        additional = models.CharField(
            max_length=1000,
            null=True,
            blank=True,
            default=None
        )
        created_at = models.DateTimeField(auto_now_add=True)

In order to catch the creation of the object, I've created a new signals.py file with the following context:

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

    from core.models import Answer

    @receiver(post_save, sender=Answer)
    def answer_question(sender, instance, **kwargs):
        print("CAUGHT A SIGNAL")
        print(instance.question.sentence, instance.answer)

But when I create a new answer it doesn't seem to trigger the signal (I'm creating it via front-end, since I'm using django-rest-framework). I don't see anything in my console other than the POST method that's going to my API.

What's wrong?

luistm
  • 1,027
  • 4
  • 18
  • 43
Desiigner
  • 2,136
  • 5
  • 26
  • 47

3 Answers3

4

We need to register our signal from AppConfig.ready() function. link and here we need to connect our signal. Hope this will solve your problem. Just one more additional thing, if your app isn't part of INSTALLED_APPS don't forget to add init.py

I would like to add an additional link, Please go through the section Where Should the Code Live? will remove your doubt.

Shakil
  • 4,520
  • 3
  • 26
  • 36
3

Django-debug-toolbar helps to get more infos about your signals. Just declare them in your settings.py:

DEBUG_TOOLBAR_CONFIG = {
    'EXTRA_SIGNALS': [
        'myapp.signals.my_signal1',
        'myapp.signals.my_signal2',
    ],
}

There's a panel showing all the signals declared to dj-toolbar and their receivers.

Zulu
  • 8,765
  • 9
  • 49
  • 56
0

You have to override ready method of application configuration class.

In apps.py application configuration class will be defined. Overide ready method as follows

from django.apps import AppConfig
class YourAppConfig(AppConfig):
    name = 'your_app'

    def ready(self):
        import your_app.signal

In project settings.py update installed apps as follows:

Replace

INSTALLED_APPS = (
 '...',
 'your_app',
)

with

INSTALLED_APPS = (
 '...',
 'your_app.apps.YourAppConfig',
)

As per django 3.0 documentation there is no need to add default_app_config in init.py https://docs.djangoproject.com/en/3.0/ref/applications/#django.apps.AppConfig.ready

ABN
  • 1,024
  • 13
  • 26
  • I spend the whole day trying to figure out why the hell my signals of creating and saving with the receiver decorator were not working. Changing from 'my_app_name' to my_app.apps.MyAppConfig' did it for me! The question now is, how the hell my app was working and Profile (in my case) for the User was created and saved before (I started working on it like a week ago and since then till today I had no issues) and out of a sudden it is not?! – Moaaz Jan 14 '21 at 22:08