什么时候在django中使用pre_save,save,post_save?

时间:2013-07-15 02:09:40

标签: python django django-models django-signals

我看到我可以覆盖或定义pre_save, save, post_save以便在保存模型实例时执行我想要的操作。

在哪种情况下哪一个首选?为什么?

3 个答案:

答案 0 :(得分:24)

我会尽力用一个例子来解释它:

模型发送的

pre_savepost_savesignals。简单来说,就是调用模型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_saveFileField并且ImageFieldfile确实存在,则可以使用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_信号,请记住这一点。