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

时间:2021-11-18 00:12:03

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.

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

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)

4 个解决方案

#1


5  

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.

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

#2


4  

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

#3


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.

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

#4


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?

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

#1


5  

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.

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

#2


4  

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

#3


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.

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

#4


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?

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