【发布时间】:2014-07-07 19:54:22
【问题描述】:
这是一个自我解释的问题,但我们开始吧。 我正在 Django 中创建一个业务应用程序,我不想在应用程序和数据库中“传播”所有逻辑,但另一方面,我不想让数据库处理这个任务(它可能通过使用Triggers)。
所以我想“重现”数据库触发器的行为,但在 Django 的模型类中(目前使用 Django 1.4)。
经过一些研究,我发现对于单个对象,我可以覆盖“models.Model”类的“save”和“delete”方法,插入“before”和“after”钩子以便它们可以被执行在父母的保存/删除之前和之后。像这样:
class MyModel(models.Model):
def __before(self):
pass
def __after(self):
pass
@commit_on_success #the decorator is only to ensure that everything occurs inside the same transaction
def save(self, *args, *kwargs):
self.__before()
super(MyModel,self).save(args, kwargs)
self.__after()
大问题在于批量操作。从 QuerySet 运行“update()”/“delete()”时,Django 不会触发模型的保存/删除。 Insted,它使用 QuerySet 自己的方法。更糟糕的是,它也不会触发任何信号。
编辑: 更具体一点:视图内的模型加载是动态的,因此不可能定义“特定于模型”的方式。在这种情况下,我应该创建一个抽象类并在那里处理它。
我最后一次尝试是创建一个自定义管理器,在这个自定义管理器中,覆盖更新方法,循环查询集中的模型,并触发每个模型的“save()”(考虑上面的实现,或“信号”系统)。它可以工作,但会导致数据库“过载”(想象一个 10k 行的查询集正在更新)。
【问题讨论】:
-
您到底想在保存前/保存后触发器中做什么?根据您的需要,有些方法可能有效,有些则无效。
-
很难说,因为每个模型可能有不同的行为。 “SaleItems”可以更新其“Sale”记录的值,而正在更新的“Sale”记录可以及时更新“BillingStatus”,等等。同样,每个模型都可能有前/后行为。
标签: python django postgresql triggers models