7

I would like to update my model object once a celery task has completed. I am currently at a loss about how to go about doing this though.

Here is a layout of the files

models.py

from photos.tasks import photo_download

class Photo(models.Model):
    ....fields....


@receiver(post_save)
def download_photo_callback(sender, **kwargs):
    photo = kwargs["instance"]
    result = photo_download.delay(photo.uid)

tasks.py

from photo.models import Photo

@task()
def photo_download(photo_uid, callback=None):
    ...do stuff...
    photo.status = 'D'
    photo.save()
Alexis
  • 23,545
  • 19
  • 104
  • 143
  • Have you tried passing the model primary key as one of the arguments to the `run` method of your task and updating your Model as the last line in the `run` method? – Praveen Gollakota Apr 24 '12 at 20:28
  • I tried passing the primary key in. But then in my `tasks.py` file I couldn't `from photo.models import Photo` – Alexis Apr 24 '12 at 20:51
  • Are all your workers on the same machine or not? – Praveen Gollakota Apr 24 '12 at 20:53
  • Probably a circular dependency... Are you trying to create tasks from your models file? – Sam Dolan Apr 24 '12 at 20:53
  • oh goodness... it is the same machine now. But in the future it will be different machines – Alexis Apr 24 '12 at 20:59
  • What is the right thing to do when it is on the same machine? What is the right thing to do when it is on different machines? – Alexis Apr 24 '12 at 21:00
  • I am not sure why it doesn't work for you. I do the exact same thing for my project. i.e. pass the primary key and update the db table in a celery task and works fine. May be as @sdolan suggested, it could be a circular import issue. – Praveen Gollakota Apr 24 '12 at 21:06
  • yeah... I am creating tasks from my model file. Is that bad? I am using a `post_save` signal to create a celery task – Alexis Apr 24 '12 at 21:14
  • @AlexisK That's not bad, but why do you need this line `from photo.models import Photo` if your tasks are inside models? – Praveen Gollakota Apr 24 '12 at 21:16
  • my tasks are in a `tasks.py` file. I'll update the original questions with a layout – Alexis Apr 24 '12 at 21:19

3 Answers3

5

You're doing a circular import. Your tasks.py file is importing your models.py file and vice-versa. You should move your signals to a separate signals.py file to avoid it.

Sam Dolan
  • 31,966
  • 10
  • 88
  • 84
  • where should the `signals.py` file go? In the app or in the project? What should then import the `signals.py` file? – Alexis Apr 24 '12 at 21:44
  • The naive way to break it out, you'd have models import signals which would import tasks which would import models, still giving you a circular import. What's a reliable way to register signal handlers if not directly by the model? Or how else would you break the (3-way instead of 2-way) circular import? – Jamie B Apr 29 '14 at 18:47
  • Further investigation yielded [this discussion](http://stackoverflow.com/a/11483929/2246212) of a project structure to avoid circular imports for model-dependent tasks triggered by model signals. Also note the comment about passing in a `dispatch_uid` argument to prevent duplicate signals. – Jamie B May 01 '14 at 15:57
1

There is an example in documentation:

http://docs.celeryproject.org/en/latest/userguide/tasks.html#example

See spam_filter task:

http://docs.celeryproject.org/en/latest/userguide/tasks.html#blog-tasks-py

bmihelac
  • 6,233
  • 34
  • 45
  • Sure it does, ``spam_filter`` task in documentation example updates comment instance when task is finished and that was the question. – bmihelac Dec 08 '14 at 14:34
0

Have the other side read your Django settings so that it can update the model easily.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • this looks good. Is there a more detailed guide on setting up celery to be able to modify the dispatchers database? – Alexis Apr 24 '12 at 20:56
  • Once you've loaded the settings you can import from the project and manipulate it just as you would *within* the project (provided `sys.path` is modified appropriately). – Ignacio Vazquez-Abrams Apr 24 '12 at 21:14