Jak @dotz zmínil , je stěží užitečné vytvořit asynchronní úlohu a okamžitě ji zablokovat a čekat na její dokončení.
Navíc, pokud se k němu připojíte tímto způsobem (.get()
na konci), můžete si být jisti, že mymodel
Právě provedené změny instance váš pracovník neuvidí, protože ještě nebudou potvrzeny – nezapomeňte, že jste stále uvnitř atomic
blokovat.
Místo toho můžete (od Django 1.9) odložit úlohu do doby, než bude aktuální aktivní transakce potvrzena, pomocí django.db.transaction.on_commit
háček:
from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
Tento vzor používám poměrně často ve svém post_save
manipulátory signálů, které spouštějí určité zpracování nových instancí modelu. Například:
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))
Tímto způsobem však váš úkol nebude proveden pokud databázová transakce selže. Obvykle je to žádoucí chování, ale mějte to na paměti.
Upravit :Ve skutečnosti je lepší zaregistrovat úlohu celeru on_commit tímto způsobem (bez lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)