Django - Executing a task through celery from a model

后端 未结 3 1388
时光取名叫无心
时光取名叫无心 2021-02-06 03:50

In my models.py:

from django.db import models
from core import tasks

class Image(models.Model):
    image     = models.ImageField(upload_to=\'images/orig\')
            


        
相关标签:
3条回答
  • 2021-02-06 04:33

    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)
    
    0 讨论(0)
  • 2021-02-06 04:39

    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)
    
    0 讨论(0)
  • 2021-02-06 04:44

    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
    
    0 讨论(0)
提交回复
热议问题