如何在Django中使用Celery从request.FILES上传文件?

twh00eeo  于 2023-08-08  发布在  Go
关注(0)|答案(1)|浏览(123)

有一个叫做Post的模型,它有一个图像字段。image字段从窗体获取其值。我不希望媒体文件存储在本地。所以我使用S3Boto3Storage作为文件存储。有没有一种方法可以使用celery保存Post模型对象(这样celery就可以上传图片文件,而不会让用户等待)。我试着写一个celery 任务来保存对象。但显然你不能只把文件作为参数发送给Celery。这是我到目前为止所拥有的:
网址:views.py

tasks.upload_image_task.delay(
    user_pk,
    post_body,
    request.FILES.get("image"),
)

字符串
网址:tasks.py

@shared_task
def upload_image_task(user_pk, body, image):
    user = User.objects.get(pk=user_pk)
    post = Post.objects.create(user=user, body=body, image=image, post_type="IMG")
    post.save()


这将导致Object of type InMemoryUploadedFile is not JSON serializable。我还读到,首先你可以保存文件在本地,然后使用任务上传文件。但我想直接上传。

9ceoxa92

9ceoxa921#

Amazon S3有一个预签名post url的概念,你可以使用它直接从用户浏览器上传照片,而不是从你的django后端上传。这应该会使您的API更快,但您仍然需要等待文件上传到浏览器上。
但是由于其他原因,如果你仍然想将图片发布到后端,你不能使用celery ,除非你有公共的文件存储可以从celery worker和django进程访问。在这种情况下,您可以首先在本地保存文件,并将路径发送到celery 任务输入参数。但是如果您没有这样的存储,您可以在发送响应后异步运行文件上传。你可以找到关于here的答案。

相关问题