@dotz言及 として 、非同期タスクを生成し、すぐにブロックして、終了するまで待機し続けることはほとんど役に立ちません。
さらに、この方法でアタッチすると(.get()
最後に)、mymodel
行ったばかりのインスタンスの変更は、まだコミットされていないため、ワーカーには表示されません。まだatomic
内にいることを忘れないでください。 ブロック。
代わりに(Django 1.9から)できることは、django.db.transaction.on_commit
を使用して、現在アクティブなトランザクションがコミットされるまでタスクを遅らせることです。 フック:
from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
私はこのパターンをpost_save
で頻繁に使用しています 新しいモデルインスタンスの処理をトリガーするシグナルハンドラ。例:
from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver
from . import models # Your models defining some Order model
from . import tasks # Your tasks defining a routine to process new instances
@receiver(post_save, sender=models.Order)
def new_order_callback(sender, instance, created, **kwargs):
""" Automatically triggers processing of a new Order. """
if created:
transaction.on_commit(lambda:
tasks.process_new_order.delay(instance.pk))
ただし、この方法では、タスクは実行されません データベーストランザクションが失敗した場合。これは通常、望ましい動作ですが、覚えておいてください。
編集 :on_commitセロリタスクをこの方法で登録する方が実際には優れています(ラムダなし):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)