educampver
educampver

Reputation: 3005

Receiver doesn't notice signal launch

I know this has been asked and answered before, but none of the proposed solutions has worked for me. This is my signals.py:

from django.dispatch import Signal

my_signal = Signal(providing_args=['arg1', 'arg2', 'arg3'])

In the other hand, I have a file called handlers.py which looks like this:

from django.dispatch import receiver
from models import MyModels
from signals import my_signal

@receiver(my_signal, sender=MyModel)
def do_something(sender, **kwargs):
    print 'I'm doing nothing!!!'

I'm sending the signal in another file which looks like this:

from signals import my_signal
from models import MyModel

def some_function():
    my_signal.send(MyModel, arg1='a', arg2='b', arg3='c')

I don't know what to do. When I send the signal django doesn't complain, but the code in do_something function is never reached, is like the receiver wasn't working well or listening to the wrong kind of signal. Anyone?

Upvotes: 0

Views: 254

Answers (3)

dcripplinger
dcripplinger

Reputation: 135

Your code is likely not generating a .pyc because you have an syntactical error:

    print 'I'm doing nothing!!!'

If you are going to have a single quote inside your string, you need to mark the string with double quotes, or use an escape sequence.

Upvotes: 0

educampver
educampver

Reputation: 3005

I finally found the solution!!! I noticed that handlers.py didn't had a generated handlers.pyc, which looked odd to me. So what I did was importing handlers.py in my __init__.py to tell django that this file exist and it worked perfectly. What I don't understand well is why. I believe it could be because that file wasn't directly referenced from anywhere in my code, just set as receiver of a signal but never explicitly called.

Upvotes: 2

kkd
kkd

Reputation: 95

When you define signals in django, you will need to register them. The best place to register it is in your models.py. To register your function do_something, move the code to the bottom of your models.py file:

.
.
@receiver(my_signal, sender=MyModel)
def do_something(sender, **kwargs):
    print 'I'm doing nothing!!!'

If you prefer to keep all your handlers in a separate file(handlers.py), you will need to import it in your models.py file. Put this line of code at the bottom of your models.py:

.
.
from handlers.py import do_something

Note: Your must be careful with circular imports when registering handlers in a different file. This line can be harmful:

from models import MyModels

To still be able to get the model in your handlers.py, you can do this:

from django.db import get_model
my_model = get_model('<app_name>', '<model_name>')

Upvotes: 3

Related Questions