This is a simple way to use Celery without writing your own tasks for models. This makes it super, duper easy to port an existing legacy app to async. All you have to do is...
fromdelay_method.modelsimportDelayedMethodModelclassYourModel(DelayedMethodModel)
# ......and...
instance.call_delay('method_name', *args, **kwargs)A demo is worth a thousand words...
fromdjango.dbimportmodelsfromdelay_method.modelsimportDelayedMethodModelclassPerson(DelayedMethodModel):
added=models.DateTimeField(auto_now_add=True)
name=models.CharField(max_length=100)
skill=models.CharField(max_length=255)
friends=models.ManyToManyField('self')
deftogether(self):
return'{0} is great at {1}.'.format(self.name, self.skill)
deflikes(self, *args):
return'{0} likes {1}.'.format(self.name, ', '.join(args))
defputs(self, **kwargs):
puts=' and '.join(
['the {0} in the {1}'.format(k,v) fork,vinkwargs.items()]
)
return'{0} puts {1}.'.format(self.name, puts)
defalert_friends(self):
forfriendinself.friends.all():
# send an email!passfromdjango.httpimportHttpResponsefrommyapp.modelsimportPersondefcombine_view(request, person_id):
""" Collecting multiple slow to compute things to return to the user at the same time. """person=Person.objects.get(id=person_id)
# equivalent to person.together()task1=person.call_delay('together')
# equivalent to person.likes('cats', 'dogs)task2=person.call_delay('likes', 'cats', 'dogs')
# equivalent to person.puts(dog='doghouse', cat='litter box')task3=person.call_delay('puts', dog='doghouse', cat='litter box')
# you'd need to collect the results....together, likes, puts=task1.wait(), task2.wait(), task3.wait()
returnHttpResponse("\n".join([together, likes, puts]))
deftrigger_view(request, person_id):
""" Let this persons friends know something is up. We don't want to call person.alert_friends() directly in the request/response cycle as that would be very slow to make the view wait on maybe hundreds of emails being sent. """person=Person.objects.get(id=person_id)
# equivalent to person.alert_friends()task=person.call_delay('alert_friends')
returnHttpResponse('Your friends will be alerted!')