Django - post_save计时问题 - 如何实现动作信号“数据库保存已完成”

时间:2013-03-13 12:13:26

标签: django signals

在我看来,好像post_save信号不是在数据库中完成整个保存过程时触发,而是在model.save()调用结束时触发。

我在执行以下代码时做了这个观察:

models.py

class PurchaseOrder(models.Model):
    total_value = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)

def purchase_order_post_save_handler(sender, instance, **kwargs):
    project_po_value_update_thread = accounting.threads.ProjectPoValueUpdateThread(instance)
    project_po_value_update_thread.start() 

post_save.connect(purchase_order_post_save_handler, sender=PurchaseOrder) 

threads.py

class ProjectPoValueUpdateThread(threading.Thread):
    """
    thread to update the po.project with the latest po values
    called via the save method of the purchase order
    """

    def __init__(self, purchase_order):
        self.purchase_order = purchase_order
        threading.Thread.__init__(self)

    def run(self):
        "starts the thread to update project po values"
        try:
            project = self.purchase_order.project
            #update active po budget
            active_po_sum = PurchaseOrder.objects.filter(project=project, is_active=True).aggregate(total_value_sum=Sum('total_value'))
            active_total_value_sum = active_po_sum['total_value_sum']
            project.total_value = active_total_value_sum
            project.save()

在某些情况下,此代码未正确更新项目total_value,因为使用PurchaseOrder.objects.filter(project = project,is_active = True)查询的实例(我刚刚保存)显然未更新。因此,在我看来,线程已经超越了实例保存方法并查询了旧版本的模型。

我知道如何克服这个特定问题(只需从post_save信号提供的实例中获取最新值),但我想知道如何创建一个post_save信号,当数据库中的保存操作完成时触发该信号

1 个答案:

答案 0 :(得分:1)

你是对的,post_save信号在save()方法结束时执行。这个事实在Django docs

  

django.db.models.signals.post_save

     

与pre_save类似,但在save()方法结束时发送。

如果您打算在多个区域使用信号,则可能更适合write your own

编辑:更好地链接信号定义