我需要连接从抽象类继承的所有类的Django信号。是否有像__on_inherit__
这样的魔术python方法,它可以让我每次继承我的抽象类时运行信号连接代码?
更新:为了澄清,我需要在课堂评估上每类运行一次代码,而不是每个实例/对象一次。
是的,确实有[__init_subclass__
] [1]钩,每次都会触发类。
将第一个参数 cls
称为 new sub类(不是原始父类(。正如文档中所述的那样,您甚至可以将任意论据传递给子类别的钩子。
希望这对您有帮助。
编辑:通过Python版本3.6中的PEP 487 [2]添加了这一点。在较早的Python版本中,此方法不称为。
[1] https://docs.python.org/3/reference/datamodel.html#object。 init_s> init_subclass
[2] https://www.python.org/dev/peps/pep-0487/
我们可以为此实现解决方案。首先,我们可以生成一个抽象模型的子类集,例如使用此解决方案:
def get_descendants(klass): gen = { klass } desc = set() while gen: gen = { skls for kls in gen for skls in kls.__subclasses__() } desc.update(gen) return desc
接下来我们可以迭代此事,每次调用一个函数,例如:
for subclass in get_descendants(AbstractModel):
# ... do something with that subclass
pass
其中 AbstactModel
是要得出子类的抽象模型。
您应该在加载应用程序时触发对此的评估,例如,在AppConfig
的 ready()
方法[django-doc]中。
这非常罕见,尤其是对于模型以后进行新的子类。对于那些非常罕见的模型,无论如何都不是一个好主意,因为当您想进行迁移时,这可能不起作用。
示例:向每个子类添加信号
我们可以通过首先定义信号处理程序来为 AbstractModel
的每个子类添加信号:
def test_signal(sender, instance, **kwargs):
print('{} is saved'.format(instance))
,然后我们可以将其与每个子类连接:
from django.db.models.signals import post_save
for subclass in get_descendants(AbstractModel):
post_save.connect(test_signal, sender=subclass)
对于Python> = 3.6,Terseus已经提到的__init__subclass__
OK。
对于较旧的python方面,挂接类创建的规范方式(我的意思是"创建新类对象"(是使用自定义元口和覆盖__new__
或__init__
方法(这是广泛记录的,所以我赢了't port示例(。