问题 添加到django模型的“构造函数”


我想在创建特定django模型的实例时进行额外的初始化。我知道 重写__init__会导致麻烦。我还应该考虑其他什么选择?

更新。额外细节: 目的是初始化该模型的实例所代表的状态机。这个状态机由一个导入的库提供,它的内部状态由我的django-model保存。我们的想法是,无论何时加载模型,状态机都将使用模型的数据自动初始化。


1438
2018-02-23 15:08


起源

你误解了这个问题。这不是最重要的 __init__ 不起作用,OP只是做错了。你可以自由覆盖 __init__,但其效果完全取决于你究竟想做什么。那你为什么不告诉我们,所以我们实际上可以帮助你。 - Chris Pratt
谢谢,我重读了另一个帖子。你的意思是,如果我保留签名 (self, *args, **kwargs),覆盖__init__不会继续django的方式? - Filipe Correia
我在问题中添加了更多信息以澄清意图。 - Filipe Correia


答案:


重写 __init__ 可能会工作,但这是个坏主意,而不是Django的方式。

在Django中使用它的正确方法是使用 信号

在这种情况下你感兴趣的是 pre_init 和 post_init

django.db.models.signals.pre_init 

每当你实例化Django时   模型,此信号在模型的开头发送 __init__()   方法。

django.db.models.signals.post_init 

喜欢 pre_init,但是这个是发送的   当。。。的时候 __init__():方法完成

所以你的代码应该是这样的

from django.db import models
from django.db.models.signals import post_init

class MyModel(models.Model):
  # normal model definition...

def extraInitForMyModel(**kwargs):
   instance = kwargs.get('instance')
   do_whatever_you_need_with(instance)

post_init.connect(extraInitForMyModel, MyModel)

您也可以将信号连接到Django的预定义模型。


14
2018-02-23 15:50



以什么方式覆盖是一个坏主意 __init__?它在django中没有比任何其他情况更多的问题。 - Marcin
vartec我知道已经有一段时间了,但我刚刚碰到你的回复,我很好奇。为什么你说信号是Django的方式?为什么不在Django文档中描述的两种方法中的一种来解决这种精确的情况呢? docs.djangoproject.com/en/1.4/ref/models/instances/... 谢谢 - oneloop
上一条评论的更新链接如下: docs.djangoproject.com/en/1.9/ref/models/instances - Alex Kreimer