4

having read the docs,

https://docs.djangoproject.com/en/dev/topics/signals/

i have created this in my signals.py file:

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

from models import Story

@receiver(post_save, sender=User)
def create_initial_story(sender,instance, signal, created, **kwargs):
    print "helloooo!"
    if created:
        Story(user = instance, title = 'Random Stories', description="Random stories", is_closed = False, is_random = True).save()

which, from what i read, was all i thought i needed to do to send a message. Well, that and create a new user (i use the django-registration framework) However, nothing is being sent (well, the receiver method i have does nothing). I also removed the "sender=User" parameter to the @receiver annotation - leaving

@receiver(post_save)

but that did not help matters. Nothing is output to the console, no new data is saved... do i need to send the signal from the User when the User is saved?? If so, how would i do that? I am using django-registration, so i have a UserProfile defined... what i mean is, where (in what file/method) would i tell the User to send the signal?

Community
  • 1
  • 1
bharal
  • 15,461
  • 36
  • 117
  • 195

3 Answers3

9

You should import your signals.py somewhere to run it. For example in models.py.

DrTyrsa
  • 31,014
  • 7
  • 86
  • 86
  • hm, am a bit new to python - so aside from the import signals line, do i need to *call* it in the models.py? Or can i just, well, import it and leave it at that? – bharal May 24 '12 at 13:57
  • 4
    @bharal Just import. You need to just run it somehow. And use `django.db.models.get_model` in `signals.py` to prevent circular imports. – DrTyrsa May 24 '12 at 14:02
6

First, they're called "decorators". Annotations are something else in Django, so best not to confuse terminology there.

The post_save signal is called, as its name implies, after every save. Specifying sender limits the receiver to just post_save signals sent for saves of that particular model. If you leave it out, your receiver will be called when any model is saved, which is surely not what you want.

Your problem here is that your receiver, for all intents and purposes doesn't exist. Django does not import automatically import signals.py for you, so it's never seen. The only way to get it seen is to import it somewhere that Django does look at, such as models.py (as @DrTyrsa) suggests.

However, if you do that, you're going to end up with a circular import error, since you're importing models.py into signals.py already. So, you can either just put your signal code directly into models.py, or find somewhere else to import it; __init__.py might work, but I normally just always put my signals in models.py and call it a day.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
0

Or you can use this:

from django.db.models.signals import post_save
Milad Hz
  • 1
  • 1
  • 1
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. –  Jul 12 '20 at 18:16