可以改变Django信号的顺序吗?

时间:2012-04-04 19:00:05

标签: django signals django-signals

我在用户注册,socialauth_registered和post_save发送了2个信号。我希望socialauth_registered在post_save之前,因为它会影响post_save触发的函数。

这可能吗? (如果是,怎么样?!)

我不确定究竟有什么相关性,但我有:

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)

4 个答案:

答案 0 :(得分:7)

我不是积极的,但我会说这是值得怀疑的。更重要的是信号背后的想法是它们应该是原子的。信号处理程序应响应信号,不应关心其他信号。依赖于两个不相关信号的顺序(显然你可以依赖于pre_save和post_save的顺序)通常是不安全的。所以即使我对你的问题没有一个坚定的答案,我也会提出你应该仔细考虑设计的建议。

答案 1 :(得分:6)

不,您无法更改执行信号的顺序。

已提出信号优先级,但核心开发人员表示他们不会实现此功能:

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

答案 2 :(得分:2)

我知道这是一个非常古老的问题,但是我发现缺少与处理程序排序的解决方法相关的任何内容都让我感到惊讶。所以这里是调度程序的子类,它实现了优先级。

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()

虽然这不能帮助您使用第三方应用,但您可以使用此类创建自己的信号,并将它们附加到内置信号,从而允许您在自己的应用中订购处理程序。 / p>

答案 3 :(得分:0)

您是否考虑使用一个调用create_social_profile和create_user_profile的信号。也许你可以把这个信号附加到post_save?