我想在保存新记录(而不是更新现有记录)时,在Django模型对象的save()方法中触发一个特殊操作。

是检查(self。id != None)有必要且充分地保证自我记录是新的且没有被更新?有没有可能被忽略的特殊情况?


当前回答

更新:与本人澄清。_state不是私有实例变量,但这样命名是为了避免冲突,检查self._state。加法现在是更好的检查方法。


self.pk is None:

在一个新的Model对象中返回True,除非对象有一个UUIDField作为它的主键。

您可能不得不担心的极端情况是,除了id之外的字段是否存在唯一性约束(例如,其他字段上的次要惟一索引)。在这种情况下,您可能仍然拥有一条新记录,但无法保存它。

其他回答

你可以连接到post_save信号,发送一个“创建”kwargs,如果为真,你的对象已经插入。

http://docs.djangoproject.com/en/stable/ref/signals/#post-save

check for self。pk == None不足以确定对象是否将被插入或更新到数据库中。

Django O/RM有一个特别讨厌的hack,基本上就是检查在PK位置是否有东西,如果有就做一个UPDATE,否则就做一个INSERT(如果PK为None,这将被优化为INSERT)。

它必须这样做的原因是允许在创建对象时设置PK。虽然在主键有序列列的地方不常见,但这不适用于其他类型的主键字段。

如果你真的想知道,你必须做O/RM所做的,并在数据库中查找。

当然,在代码中有一个特定的情况,很可能是self。pk == None告诉你所有你需要知道的,但它不是一个通解。

我很晚才谈这个话题,但我遇到了自我的问题。当Pk具有与之关联的默认值时,将填充它。

我解决这个问题的方法是在模型中添加一个date_created字段

date_created = models.DateTimeField(auto_now_add=True)

你可以从这里出发

Created = self。date_created为None

> def save_model(self, request, obj, form, change):
>         if form.instance._state.adding:
>             form.instance.author = request.user
>             super().save_model(request, obj, form, change)
>         else:
>             obj.updated_by = request.user.username
> 
>             super().save_model(request, obj, form, change)

这是常见的做法。

id将在第一次保存到db时给出