2016-07-06 53 views
0

当父模型的某个字段发生更改时,触发相关模型更新的最合适方式是什么?我有这样的一组模型:相关型号模型现场更新更新

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

class ActivityJob(models.Model): 
    activity_object = models.ForeignKey(
     ActivityObject, 
     related_name='activity_jobs', 
    ) 
    is_deleted = models.BooleanField(default=False) 

,所以如果我在某些情况下设置ActivityObject.is_deleted = True所有我想要的是ActivityJob也发生了变化领域的is_deletedTrue所有相关实例。提前致谢。

回答

1

重写保存()将工作:

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

    def save(self, *args, **kwargs): 
     super(ActivityObject, self).save(args, kwargs) 
     if self.is_deleted: 
      for job in self.activity_jobs: 
       job.is_deleted = True 
       job.save() 

只是猜测这里,但如果这样做的真正目的是为了删除ActivityJob■当相关ActivityObject s的删除,那么你可以继续和删除ActivityObject。 Django的默认行为将删除连接到它的所有ActivityJob

如果您想在删除时执行一些其他操作,请使用Django的pre_deletepost_delete信号,它将调用您在删除指定类型的对象之前/之后定义的函数。

编辑:如果你曾经使用update()关于处理ActivityObject和改变is_deleted查询集,你可以保证你在ActivityJob进行相应update(),或者你可以重写ActivityObjectqueryset功能,例如this使其自动发生。

+0

如果save()永远不会被调用? – Brian

+0

@Brian你可以提供一个例子,其中“ActivityObject”的数据库表在没有调用save()的情况下被更改吗? –

+0

@Yash Tewari我认为这是对我来说最合适的解决方案,thx – Compadre

0

您可以使用Django信号'pre_deletepost_delete。更多的细节和例子可以在Django Signals documentation中找到。

+0

我可以通过@ transaction.atomic装饰器将信号厨房的整个东西包裹起来吗?因为在上面的答案中,我可以包装整个'save'方法,并且感觉保存是否会更改父对象,并且由于某些原因相关对象不会被更改。 – Compadre

+0

这会有帮助吗? http://django-atomic-signals.readthedocs.io/en/latest/ –

+0

感谢这个答案,我明白这个解决方案在许多方面更加灵活,但它也复杂得多,包括外部依赖。如果我需要这种灵活性,我会用你的方式来解决这类问题。感谢花时间回答:) – Compadre