Python 何时在django中使用pre_save、save、post_save?
我发现我可以覆盖或定义Python 何时在django中使用pre_save、save、post_save?,python,django,django-models,django-signals,Python,Django,Django Models,Django Signals,我发现我可以覆盖或定义pre\u save、save、post\u save,以便在保存模型实例时执行我想要的操作 在哪种情况下,哪一种更受欢迎?为什么 pre_save 它在事务保存之前使用 post_save 它在事务保存后使用 post_save 例如,如果您有一个FileField或一个ImageField,您可以使用pre\u save,查看文件或图像是否确实存在 当你有一个用户档案并且你想在新的用户创建时创建一个新的档案时,你可以使用post\u save。 和是由模型发送的。
pre\u save、save、post\u save
,以便在保存模型实例时执行我想要的操作
在哪种情况下,哪一种更受欢迎?为什么
pre_save
它在事务保存之前使用
post_save
它在事务保存后使用
post_save
例如,如果您有一个FileField
或一个ImageField
,您可以使用pre\u save
,查看文件或图像是否确实存在
当你有一个用户档案
并且你想在新的用户
创建时创建一个新的档案时,你可以使用post\u save
。
和是由模型发送的。简单地说,将调用在模型的保存之前或之后执行的操作
A保存
- 发出预保存信号李>
- 对数据进行预处理李>
- 大多数字段不进行预处理-字段数据保持原样李>
- 为数据库准备数据李>
- 将数据插入数据库李>
- 发出保存后信号李>
Django确实提供了一种覆盖这些信号的方法
现在,
pre_save
信号可以在实际保存到数据库之前被覆盖以进行一些处理-例如:(我不知道一个好的例子,说明pre_save
在哪里最合适)
假设您有一个ModelA
,它存储对ModelB
的所有对象的引用,这些对象尚未编辑。为此,您可以在调用modelba
的save
方法之前注册pre\u save
信号以通知ModelA
(没有任何东西可以阻止您在此处注册post\u 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\u save
信号(这比pre\u save
更常用)
在系统中创建User
对象时,一个常见的用例是创建UserProfile
对象
您可以注册一个post_save
信号,该信号创建一个与系统中每个用户对应的UserProfile
对象
信号是保持事物模块化、明确化的一种方式。(如果我保存或更改模型B中的内容,请明确通知模型A
)
为了更好地回答这个问题,我将想出更多具体的现实例子。同时,我希望这能帮助您不要忘记递归风险。
如果使用post\u save方法调用instance.save()而不是.update方法,则应断开post\u save信号:
信号。断开(接收器=无,发送器=无,
分派_uid=None)[source]以断开接收器与信号的连接,
呼叫信号。断开()。参数如中所述
Signal.connect()。如果某个接收器为空,则该方法返回True
断开连接,否则为假
receiver参数指示要断开连接的已注册接收器。
如果使用dispatch_uid识别接收者,则可能为None
。。。然后再连接它
update()方法不要发送前置和后置信号,请记住这一点。谢谢您的详细回答。post\u save
用于创建UserProfile
的原因是,您可以在post\u save中检查实例是否创建了(而不是在pre\u save中,save),您可能希望在回答中添加pre\u save或post\u save本身与事务无关的内容。如果使用get_、create或请求级事务,则post_保存将发生在事务内部,而不是在事务之后。根据数据库的不同,您可以使用一些post_commit signal实现。对于您的pre_save
示例,您给出了一个示例来检查文件是否存在,使用signal或覆盖save方法哪个更好??因为如果我在我的pre\u save
信号中添加验证,我很难对表单产生错误。@Keda87如果你使用表单,我会覆盖表单的验证函数。不!post_save通常在原子块中调用。这意味着post_save发生在事务内部。