我看到我可以覆盖或定义pre_save, save, post_save
以便在保存模型实例时执行我想要的操作。
在哪种情况下哪一个首选?为什么?
答案 0 :(得分:24)
我会尽力用一个例子来解释它:
模型发送的 pre_save
和post_save
为signals。简单来说,就是调用模型save
之前或之后的操作。
save
triggers the following steps
Django确实提供了一种覆盖这些信号的方法。
现在,
在实际保存到数据库中之前,可以覆盖 pre_save
信号进行某些处理 - 例如:(我不知道pre_save
在我的头脑中理想的地方的一个很好的例子)
假设您有一个ModelA
,其中存储了对ModelB
的所有尚未编辑过的对象的引用。为此,您可以在调用pre_save
的{{1}}方法之前注册ModelA
信号以通知ModelB
(没有什么可以阻止您注册save
信号这里也)。
现在,调用模型的post_save
方法(它不是信号) - 默认情况下,每个模型都有save
方法,但您可以覆盖它:
save
然后,您可以注册class ModelB(models.Model):
def save(self):
#do some custom processing here: Example: convert Image resolution to a normalized value
super(ModelB, self).save()
信号(这更多地用于post_save
)
在系统中创建pre_save
对象时,常见的用例是UserProfile
对象创建。
您可以注册User
信号,该信号会创建与系统中每个post_save
对应的UserProfile
对象。
信号是保持模块化和明确化的一种方式。 (明确通知User
如果我ModelA
或更改save
中的内容
我会想到更具体的现实世界的例子,试图更好地回答这个问题。同时,我希望这可以帮助你
答案 1 :(得分:3)
pre_save
在交易保存之前使用它。
post_save
在事务保存后使用它。
如果您有pre_save
或FileField
并且ImageField
或file
确实存在,则可以使用image
。
如果您拥有post_save
,则可以使用UserProfile
,并且您希望在创建新User
时创建新的{{1}}。
答案 2 :(得分:2)
不要忘记递归风险。 如果您使用 post_save 方法调用 instance.save(),而不是.update方法,则应断开 post_save 信号:
Signal.disconnect(receiver = None,sender = None, dispatch_uid =无)[source]要断开接收器与信号的连接, 调用Signal.disconnect()。参数如下所述 Signal.connect()。如果接收器是,则该方法返回True 断开连接,否则返回False。
receiver参数表示已注册的接收器断开连接。 如果dispatch_uid用于识别接收者,则可能为None。
...并在之后再次连接。
更新()方法不发送pre-and post_信号,请记住这一点。