Seperti @dotz mention , hampir tidak berguna untuk menelurkan tugas asinkron dan segera memblokir dan terus menunggu hingga selesai.
Selain itu, jika Anda melampirkannya dengan cara ini (.get()
di akhir), Anda dapat yakin bahwa mymodel
perubahan instans yang baru saja dibuat tidak akan terlihat oleh pekerja Anda karena perubahan tersebut belum dilakukan - ingat Anda masih berada di dalam atomic
blokir.
Apa yang dapat Anda lakukan sebagai gantinya (dari Django 1.9) adalah menunda tugas hingga setelah transaksi aktif saat ini dilakukan, menggunakan django.db.transaction.on_commit
kait:
from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
Saya cukup sering menggunakan pola ini di post_save
saya penangan sinyal yang memicu beberapa pemrosesan instance model baru. Misalnya:
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))
Namun, dengan cara ini, tugas Anda tidak akan dieksekusi jika transaksi database gagal. Ini biasanya merupakan perilaku yang diinginkan, tetapi ingatlah.
Sunting :Sebenarnya lebih baik mendaftarkan tugas seledri on_commit dengan cara ini (tanpa lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)