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

eug*_*ene 26 python django django-signals django-models

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

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

kar*_*ikr 27

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

pre_save并且post_save是模型发送的信号.简单来说,save调用模型之前或之后的操作.

A save 触发以下步骤

  • 发出预保存信号.
  • 预处理数据.
  • 大多数字段不进行预处理 - 字段数据保持原样.
  • 准备数据库的数据.
  • 将数据插入数据库.
  • 发出保存后信号.

Django确实提供了一种覆盖这些信号的方法.

现在,

pre_save在实际保存到数据库之前,可以覆盖信号进行某些处理 - 例如:(我不知道pre_save在我的脑海中哪里理想的一个很好的例子)

比方说你有一个ModelA存储引用的所有对象ModelB被编辑呢.对于这一点,你可以注册一个pre_save信号,通知ModelA权利之前ModelBs"的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()
Run Code Online (Sandbox Code Playgroud)

然后,你可以注册post_save信号(这是更常用的pre_save)

一个常见的用例是在系统中创建UserProfile对象时创建User对象.

您可以注册一个post_save信号,该信号创建一个与系统中的UserProfile每个对应的对象User.

信号是保持模块化和显式化的一种方式.(ModelA如果我save改变了某些内容,请明确通知ModelB)

为了更好地回答这个问题,我会想到更具体的现实世界的例子.同时,我希望这会对你有所帮助


Vic*_*res 5

pre_save
Run Code Online (Sandbox Code Playgroud)

它在交易保存之前使用。

post_save
Run Code Online (Sandbox Code Playgroud)

交易保存后使用。

pre_save例如,您可以使用如果您有 aFileField或 anImageField 并查看 thefile或 the是否image确实存在。

post_save当您有一个UserProfile并且您想在创建新的那一刻创建一个新的时,您可以使用它User

  • 没有!post_save 通常在原子块中调用。这意味着 post_save 发生在事务*内部*。 (2认同)

Slo*_*man 5

不要忘记递归风险。如果你使用post_save方法和instance.save()调用,而不是 .update 方法,你应该断开你的post_save信号:

Signal.disconnect(receiver=None, sender=None, dispatch_uid=None)[source] 要断开接收者与信号的连接,请调用 Signal.disconnect()。参数如 Signal.connect() 中所述。如果接收器断开连接,则该方法返回 True,否则返回 False。

接收器参数指示已注册的接收器要断开连接。如果使用 dispatch_uid 来标识接收者,则可能为 None。

...然后再连接。

update()方法不发送 pre_ 和 post_ 信号,记住这一点。