In my models.py:
from django.db import models
from core import tasks
class Image(models.Model):
image = models.ImageField(upload_to=\'images/orig\')
1) Is what I'm trying to do considered a best practice? If yes, how do I work it out?
Yes, passing only a little information to the task is generally a good thing like you mentioned.
2) I have noticed in all the examples I found around the web, they execute the task from a view and never from a model. I'm trying to create a thumbnail whenever a new image is uploaded, I don't want to call create_thumbnail in every form/view I have. Any idea about that? Is executing a task from a model not recommended or a common practice?
I've noticed the same thing, and feel that tutorials and documentation call tasks from their views because it is easier to demonstrate how things work using simple views than with models or forms.
To eliminate circular imports, you should think about which way the imports should happen. Generally, tasks.py will need to import many things from models.py whereas models.py rarely needs to know anything about tasks.py. The standard should be that models.py does not import from tasks.py. Thus, if you do need to do this and are calling a task from a model method, make the import in the method as so:
from django.db import models
class Image(models.Model):
image = models.ImageField(upload_to='images/orig')
thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
from core.tasks import create_thumbnail
create_thumbnail.delay(self.id)
You don't need to import the task itself. Try using the following
from django.db import models
from celery.execute import send_task, delay_task
class Image(models.Model):
image = models.ImageField(upload_to='images/orig')
thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
result = delay_task("task_prefix.create_thumbnail", post.id)
i wonder if the problem might be a circular import (models
and tasks
importing each other at the top level). try moving "from core.models import Image
" into create_thumbnail
, i.e. changing tasks
to
from celery.decorators import task
@task()
def create_thumbnail(image_id):
from core.models import Image
ImageObj = Image.objects.get(id=image_id)
# other stuff here