1

データベースで保存プロセス全体が終了したときではなく、model.save() 呼び出しの最後に post_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) 

スレッド.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()

場合によっては、PurchaseOrder.objects.filter(project=project, is_active=True) で照会されたインスタンス (保存したばかり) が明らかに更新されなかったため、このコードはプロジェクトの total_value を正しく更新しませんでした。したがって、スレッドがインスタンス保存メソッドを追い越し、モデルの古いバージョンを照会したように私には思えます。

この特定の問題を克服する方法は知っていますが (post_save シグナルによって提供されるインスタンスから最新の値を取得するだけです)、データベースの保存アクションが終了したときにトリガーされる post_save シグナルを作成する方法を知りたいです。

4

1 に答える 1

1

そうです、post_save シグナルは save() メソッドの最後で実行されます。その事実はDjango docsにあります:

django.db.models.signals.post_save

pre_save と同様ですが、save() メソッドの最後に送信されます。

複数の領域でシグナルを使用することが意図されている場合は、独自の.

編集: シグナル定義へのより良いリンク

于 2013-03-13T12:27:42.043 に答える