0

In a Django website of mine, users upload photos and others comment on them. Currently, the whole uploading process is a blocking call. So instead, I want to move it to a celery queue and execute it asynchronously. For that, I simply call the following from views.py:

photo = form.cleaned_data.get('photo',None)
upload_photo.delay(photo, request.user.id)

And then in tasks.py, I have:

@celery_app1.task(name='tasks.upload_photo')
def upload_photo(photo_obj, user_id):
    photo = Photo.objects.create(image_file = photo_obj, owner_id=user_id)

Now this, predictably, gives me an EncodeError: <InMemoryUploadedFile: temp.jpg (image/jpeg)> is not JSON serializable. So what's the right pattern to follow here in order to do the heavy lifting in an aysnc task? An illustrative example would be very helpful.

P.s. in case it matters to the answerer, I'm looking for a solution with no JS involvement.

Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

1 Answers1

0

To deal with your issue you can create custom JSON encoder to be used by celery as explained for example Celery: is there a way to write custom JSON Encoder/Decoder? . But this is not good approach.

But in general, it looks like wrong solution. If the only thing you do in task is create object - do this in view. You only skip single SQL query. If media is stored on remote server, this can be a case, but better to implement it in other way (split object creation into two parts and so on).

If in task you have some other code to process image for example, it's better to leave only this code in task and create object in view.

Zada Zorg
  • 2,778
  • 1
  • 21
  • 25