Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 何时在django中使用pre_save、save、post_save?_Python_Django_Django Models_Django Signals - Fatal编程技术网

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发生在事务内部。