Django-如何在模型Mixin内部动态创建信号

时间:2019-09-02 09:49:11

标签: python django django-models django-signals

我正在研究模型Mixin,该模型需要根据一个属性动态设置信号。

它更复杂,但为简单起见,假设Mixin具有以下属性:

models = ['app.model1','app.model2']

此属性在model中定义,该属性扩展了此混合。

如何动态注册信号?

我试图创建一个类方法:

@classmethod
def set_signals(cls):
    def status_sig(sender, instance, created, *args, **kwargs):
        print('SIGNAL')
        ... do som things

    for m in cls.get_target_models():
        post_save.connect(status_sig,m)

我的想法是在类中的某个地方自动调用此方法(例如__call__方法),但现在,我只是尝试先调用它,然后再save调用模型以查看它是否有效,但是没有。

from django.db.models.signals import post_save

print(post_save.receivers)
Realestate.set_signals()
print(post_save.receivers)

r = Realestate.objects.first()
r.status = 1
r.save()

输出

[]
[((139967044372680, 46800232), <weakref at 0x7f4c9d702408; dead>), ((139967044372680, 46793464), <weakref at 0x7f4c9d702408; dead>)]

因此,您看到它注册了那些模型,但保存完房地产后未触发任何信号。

您知道如何使其工作吗?无需显式调用方法甚至更好?

编辑:

我不能只将信号创建放在mixin文件中,因为模型取决于子模型中的字符串。

1 个答案:

答案 0 :(得分:0)

如果您尚未解决此问题:

connect方法中,设置weak=False。默认情况下为True,因此,如果对象实例被垃圾回收,则本地定义的函数引用将丢失。

这很可能是您的status_sig函数所发生的;正如您在post_save接收者的打印输出中看到的那样,weakref已经死了,因此总是只返回None

Django docs中:

  

弱–默认情况下,Django将信号处理程序存储为弱引用。因此,如果您的接收器是本地函数,则可能会对其进行垃圾回收。为了防止这种情况,请在调用信号的connect()方法时传递weak = False。

有关weakref的更多信息,请参见Python docs