Som @dotz nævnt , er det næppe nyttigt at afføde en async-opgave og straks blokere og blive ved med at vente, indtil den er færdig.
Desuden, hvis du knytter til det på denne måde (.get()
til sidst), kan du være sikker på, at mymodel
instansændringer, der netop er foretaget, vil ikke blive set af din medarbejder, fordi de ikke vil blive begået endnu - husk, at du stadig er inde i atomic
blokere.
Hvad du kunne gøre i stedet (fra Django 1.9) er at forsinke opgaven, indtil den aktuelle aktive transaktion er begået, ved at bruge django.db.transaction.on_commit
krog:
from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
Jeg bruger dette mønster ret ofte i min post_save
signalhandlere, der udløser en vis behandling af nye modelforekomster. For eksempel:
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))
På denne måde vil din opgave dog ikke blive udført hvis databasetransaktionen mislykkes. Det er normalt den ønskede adfærd, men husk det.
Rediger :Det er faktisk bedre at registrere on_commit selleri opgaven på denne måde (uden lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)