Както @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 celery по този начин (без ламбда):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)