2011-11-12 33 views
8

在我的models.py執行任務Django的通過芹菜從模型

from celery.decorators import task 
from core.models import Image 

@task() 
def create_thumbnail(image_id): 
    ImageObj = Image.objects.get(id=image_id) 
    # other stuff here 

這是返回以下:

  • 例外類型:導入錯誤
  • 異常值:不能導入名稱的任務

,如果我在tasks.py註釋掉from core.models import Image,但是這顯然會造成問題,因爲Image在這裏沒有任何意義的錯誤消失。我試圖在create_thumbnail之內導入它,但它仍然不會識別Image

我讀過的地方,通常對象本身可以作爲參數傳遞給任務,這將解決我的問題。然而,一位朋友曾告訴我,在RabbitMQ消息中發送儘可能少的數據被認爲是最佳實踐,所以爲了實現這一點,我試圖只傳遞圖像ID,然後在任務中再次檢索它。

1)我試圖做的是考慮最佳實踐嗎?如果是,我該如何解決?

2)我注意到在我發現的所有例子中,他們都是從視圖執行任務,而不是從模型執行任務。我試圖在新圖片上傳時創建縮略圖,我不想在每個表單/視圖中調用create_thumbnail。任何想法呢?正在執行一個不被推薦或慣例的模型的任務嗎?

回答

13

1) Is what I'm trying to do considered a best practice? If yes, how do I work it out?

是的,只有通過一點點信息的任務一般是一件好事,像你提到的。

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?

我發現同樣的事情,覺得從他們的觀點教程和文檔調用任務,因爲它更容易證明的東西是如何工作的使用比模型或形式簡單的看法。

要消除循環導入,您應該考慮導入應該採用哪種方式。通常,tasks.py將需要從models.py導入很多東西,而models.py很少需要知道有關tasks.py的任何內容。標準應該是models.py不會從tasks.py中導入。因此,如果你需要做到這一點,並呼籲從模型方法的任務,使該方法使進口:

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) 
+1

我真的讚賞這一段:「爲了消除循環進口,你應該考慮進口應該發生的方式......」。謝謝。 – pawelmech

1

我不知道這個問題是否可能是一個循環導入(modelstasks導入對方在頂層)。嘗試移動「from core.models import Image」爲create_thumbnail,即改變tasks

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

我已經試過了,在這種情況下發送消息正確但create_thumbnail產生一個錯誤: '文件「/home/ubuntu/project/core/tasks.py」,行5,in create_thumbnail' 'from core.models import Image' 'NameError:global name'Image'is not defined' – abstractpaper

+0

我推測'core'是你的應用程序的名稱。你有沒有嘗試過項目名稱(例如'from project.app.models import Model')? django做了一些有時候不足以幫助的路徑魔術 – second

+0

剛剛做過,同樣的錯誤返回:'NameError:全局名''圖像'未定義。我已經在'django.wsgi'中追加了我的項目路徑。 – abstractpaper

4

你並不需要導入任務本身。嘗試使用以下

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) 
+1

celery.execute似乎不再存在於芹菜3.x中 – Titusz