从Django信号转向重写save方法:如何转换post_save的created参数
替换post_save的created判断:重写save方法
要在重写的save方法里区分新建/更新对象,有两种可靠方式:
方式一:检查主键pk是否为None
新建的Django模型实例在保存前pk是None,保存后才会被赋值。按原post_save的逻辑(保存后执行方法),代码示例:
class MyModel(models.Model): name = models.CharField(max_length=100) def do_something(self): print(f"处理新对象:{self.name}") def save(self, *args, **kwargs): is_created = self.pk is None # 先调用父类save完成数据库写入,和原post_save时机对齐 super().save(*args, **kwargs) if is_created: self.do_something()
方式二:用_state.adding属性判断
如果你的模型用了自定义主键(保存前就手动设置了pk),pk is None会失效,这时候用模型实例的_state.adding属性更准确——它直接标记该实例是否是要新增到数据库的:
def save(self, *args, **kwargs): is_created = self._state.adding super().save(*args, **kwargs) if is_created: self.do_something()
pre_save信号的适配逻辑
pre_save信号也能做同样的新建判断,逻辑和post_save一致,只是触发时机在保存前:
from django.db.models.signals import pre_save from django.dispatch import receiver @receiver(pre_save, sender=MyModel) def handle_mymodel_pre_save(sender, instance, **kwargs): is_created = instance._state.adding if is_created: instance.do_something()
注意:如果do_something需要用到数据库中生成的主键或其他保存后才有的数据,pre_save就不适用,这时候还是用post_save或者重写save时先保存再执行方法更稳妥。
内容的提问来源于stack exchange,提问作者V. Brunelle
相关产品推荐
相关产品推荐

