2011-11-12 29 views
8

Trong models.py tôi:Django - Thi một nhiệm vụ thông qua cần tây từ một mô hình

from django.db import models 
from core import tasks 

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) 
     tasks.create_thumbnail.delay(self.id) 

Trong tasks.py tôi:

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 

này được trả lại như sau:

    Loại
  • Ngoại lệ: ImportError
  • ngoại lệ giá trị gia tăng: không thể import nhiệm vụ tên

Các lỗi biến mất nếu tôi nhận xét ra from core.models import Image trong tasks.py, tuy nhiên điều này rõ ràng sẽ gây ra một vấn đề vì Image không có ý nghĩa ở đây. Tôi đã cố gắng để nhập khẩu nó bên create_thumbnail tuy nhiên nó vẫn sẽ không nhận ra Image.

Tôi đã đọc ở đâu đó rằng thường là đối tượng chính nó có thể được thông qua như là một cuộc tranh cãi với một nhiệm vụ và điều đó sẽ giải quyết vấn đề của tôi. Tuy nhiên, một người bạn đã từng nói với tôi rằng nó được coi là thực hành tốt nhất để gửi ít dữ liệu càng tốt trong một tin nhắn RabbitMQ, vì vậy để đạt được điều đó tôi đang cố gắng để vượt qua chỉ ID hình ảnh và sau đó lấy nó một lần nữa trong nhiệm vụ.

1) phải là những gì tôi đang cố gắng để làm được coi là một thực hành tốt nhất? Nếu có, làm thế nào để tôi làm việc nó ra?

2) Tôi đã nhận thấy trong tất cả các ví dụ tôi tìm thấy khắp nơi trên web, họ thực hiện nhiệm vụ từ một cái nhìn và không bao giờ từ một mô hình. Tôi đang cố gắng tạo một hình thu nhỏ bất cứ khi nào một hình ảnh mới được tải lên, tôi không muốn gọi create_thumbnail trong mọi hình thức/chế độ xem mà tôi có. Bất kỳ ý tưởng về điều đó? Đang thực hiện tác vụ từ một mô hình không được khuyến nghị hoặc thực hành phổ biến?

Trả lời

13

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

Vâng, chỉ đi qua một ít thông tin với nhiệm vụ nói chung là một điều tốt như bạn đề cập.

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?

Tôi đã nhận thấy điều tương tự, và cảm thấy rằng hướng dẫn và nhiệm vụ gọi tài liệu từ quan điểm của họ vì nó là dễ dàng hơn để chứng minh cách làm việc sử dụng quan điểm đơn giản hơn với các mô hình hoặc các hình thức.

Để loại bỏ nhập khẩu vòng tròn, bạn nên suy nghĩ về cách thức mà việc nhập khẩu sẽ xảy ra. Nói chung, tasks.py sẽ cần nhập nhiều thứ từ models.py trong khi models.py hiếm khi cần biết bất kỳ điều gì về tasks.py. Tiêu chuẩn phải là models.py không nhập từ tasks.py. Do đó, nếu bạn cần thực hiện việc này và đang gọi một tác vụ từ phương thức mô hình, hãy nhập phương thức như sau:

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

Tôi thực sự đánh giá cao đoạn" Để loại bỏ nhập khẩu vòng tròn, bạn nên suy nghĩ về cách nhập khẩu sẽ xảy ra ... ". Cảm ơn bạn. – pawelmech

1

tôi tự hỏi nếu sự cố có thể là nhập vòng tròn (modelstasks nhập lẫn nhau ở cấp cao nhất). hãy thử di chuyển "from core.models import Image" vào create_thumbnail, ví dụ: thay đổi 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

Tôi đã cố gắng đó, trong trường hợp này được thông báo sẽ được gửi một cách chính xác tuy nhiên create_thumbnail tạo ra một lỗi: File "/home/ubuntu/project/core/tasks.py" ', dòng 5, trong create_thumbnail' 'từ nhập khẩu core.models Hình ảnh' ' TênError: tên chung 'Hình ảnh' không được xác định ' – abstractpaper

+0

tôi giả sử' core' là tên ứng dụng của bạn. bạn đã thử thêm tên dự án (tức là 'từ mô hình nhập khẩu project.app.models')? django làm một số con đường ma thuật mà đôi khi ít hơn hữu ích – second

+0

Chỉ cần làm, cùng một lỗi trả về: 'NameError: tên toàn cầu 'Hình ảnh' không được định nghĩa'. Tôi đã nối thêm đường dẫn dự án của mình trong 'django.wsgi'. – abstractpaper

4

Bạn không cần nhập nhiệm vụ.Hãy thử sử dụng sau

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 dường như không còn tồn tại nữa trong cần tây 3.x – Titusz

Các vấn đề liên quan