Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django signals not working when placed outside models.py

I'm trying to print some text after Django model in an app has been saved.

I have created a signal for that in a signals.py file in the same application.

However, it's not working as expected (i.e., the function is not being called and text is not being printed)

But if I place the receiver function in the models.py file just below the model that I created, it's working fine (i.e., the function is being called and text has been printed)

I have gone through the documentation to check if there is any need to place the signals in a specific file or location. It looks like there isn't any such restriction.

https://docs.djangoproject.com/en/3.0/topics/signals/#django.dispatch.receiver

Why is this behaving differently if there is no such restriction?

signals.py:

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

@receiver(post_save, sender=UserStack)
def create_user_stack(sender, **kwargs):
    print("creating user stack now")

models.py:

class UserStack(BaseModel):

    name = models.CharField(max_length=50)
    email = models.EmailField(unique=True, max_length=50, blank=False)
    enabled = models.BooleanField(default=True)

    def save(self, *args, **kwargs):
        print(f"Creating stack with data: {self.name, self.email}")
        super(UserStack, self).save(*args, **kwargs)

    def __str__(self):
        return self.name, self.email
like image 238
Underoos Avatar asked Sep 05 '25 03:09

Underoos


1 Answers

  1. in INSTALLED_APPS you should register like this:

'post.apps.PostConfig'

I.e. in settings.py replace

INSTALLED_APPS = (
 '...',
 'post,
)

with

INSTALLED_APPS = (
 '...',
 'post.apps.PostConfig',
)
  1. in apps.py you shoud add these:
from django.apps import AppConfig

class postConfig(AppConfig):
    name = 'post'

    def ready(self):
        # signals are imported, so that they are defined and can be used
        import post.signals
  1. created a file in app's folder
# post/signals.py
from django.dispatch import receiver
from django.db.models.signals import post_save
from post.models import Post

def send():
    print("send email!")

@receiver(post_save, sender=Post, dispatch_uid='Post_post_save')
def send_email(instance, **kwargs):
    send()
like image 177
Ginta Avatar answered Sep 07 '25 23:09

Ginta