Possible to change order of Django signals?

Go To StackoverFlow.com

5

I've got 2 signals being sent at user registration, socialauth_registered and post_save. I'd like for socialauth_registered to precede post_save, as it affects the function that post_save triggers.

Is this possible? (and if it is, how?!)

I'm not sure what exactly is relevant, but I've got:

from django.contrib.auth.models import User
from social_auth.signals import socialauth_registered, pre_update
from django.db.models.signals import post_save

<ALL OF MY MODELS>

def create_user_profile(sender, instance, created, **kwargs):
    do some stuff

def create_social_profile(sender, user, response, details, **kwargs):
    do other stuff

socialauth_registered.connect(create_social_profile, sender=None)
post_save.connect(create_user_profile, sender=User)
2012-04-04 19:00
by Matt Parrilla


6

I'm not positive, but I'd say it's doubtful. Kinda more important is that the idea behind signals is that they should be atomic. A signal handler should respond the signal and shouldn't care about other signals. Relying on the order of two unrelated signals (obviously you can rely on the order of pre_save and post_save for example) is not safe in general. So even though I don't have a firm answer on your question, I'd offer the advice that yo should think carefully about the design.

2012-04-04 19:11
by John
Thanks for the advice. I ended up backing off the signal idea and tried a different approach that is definitely superior. While you didn't explicitly answer the question, you told me that it wasn't the right question to be asking, which was probably the best answer I could have gotten - Matt Parrilla 2012-04-08 21:27


5

No, you cannot change the order that signals are executed.

Signal priority has been proposed, but the core developers have said they will not implement this feature:

https://code.djangoproject.com/ticket/16547

2014-03-30 15:10
by Derek Curtis
This should be the correct answer. While the marked one has more content, this is the definite one - Teekin 2018-03-15 21:02


1

I know this is a very old question, but I was surprised by the lack of anything I found related to a workaround for handler ordering. So here is a subclass of the dispatcher which implements priorities.

from django.dispatch import Signal as BaseSignal
from django.dispatch.dispatcher import _make_id


class Signal(BaseSignal):

    def connect(self, receiver, sender=None, weak=True, dispatch_uid=None, priority=50):
        if dispatch_uid is None:
            dispatch_uid = _make_id(receiver)

        inner_uid = '{0}{1}'.format(priority, dispatch_uid)
        super(Signal, self).connect(receiver, sender=sender, weak=weak, dispatch_uid=inner_uid)
        self.receivers.sort()

While this won't help you with third-party apps, you can create your own signals with this class, and attach them to the built-in signals, allowing you to order the handlers within your own app.

2016-08-11 19:33
by AgDude


0

Have you considered using one signal that calls create_social_profile and create_user_profile. perhaps you could attach this signal to post_save?

2012-04-04 19:14
by Al W
Unfortunately no. The postsave is triggered every time a User object is created while the socialauthregistered is only triggered when a user registers through a 3rd party. For regular users, we confirm email, this is unnecessary for socialauth users, so we'd like to prevent that from happening. Ideally, regular registration would trigger postsave and social registration would trigger socialauthregistered - Matt Parrilla 2012-04-04 19:47
Ads