这是我的创建功能:
def create(self,request,*args,**kwargs):
serializer = ArchiveSerializer( data = request.data, context = {"request":request} )
serializer.is_valid(raise_exception=True)
filename=serializer.validated_data.pop('file')
serializer.save()
id = serializer.validated_data.get("id")
save_file_in_background.delay(id,filename)
return Response(serializer.data, status=status.HTTP_201_CREATED)
这是tasks.py
from celery import shared_task
from django.core.files.base import ContentFile
from .models import Archive
@shared_task
def save_file_in_background(id,filename):
try:
archive = Archive.objects.get(pk=id)
if filename:
archive.file.save(filename, ContentFile(filename))
archive.save()
except Archive.DoesNotExist:
pass
但是当尝试添加对象并上传文件时出现此错误: TemporaryUploadedFile 类型的对象不可 JSON 序列化
除了在后台上传文件但出现此错误: “TemporaryUploadedFile 类型的对象不可 JSON 序列化”
发生错误是因为
TemporaryUploadedFile
(上传的文件)无法直接传递给celery,因为它不是json可序列化的。您在这里可以做的是在创建实例时保存文件并仅传递 ID 以避免序列化。
但我认为你想卸载图像发布任务而不阻塞主要请求-响应周期。
您可以通过首先仅保存基本详细信息(不包括图像)的最小数据并向客户端返回响应来做到这一点。然后将任何所需信息传递给 Celery 任务来处理图像上传。
from rest_framework import status
from rest_framework.response import Response
from .tasks import upload_image_background_task
def create(self, request, *args, **kwargs):
serializer = ArchiveSerializer(data=request.data, context={"request": request})
serializer.is_valid(raise_exception=True)
# initially save the instance without image
archive_instance = serializer.save(file=None)
# take the uploaded image file from the request
uploaded_image = request.FILES.get('file')
# pass the instance id and the image data to the background task
upload_image_background_task.delay(archive_instance.id, uploaded_image.read(),
uploaded_image.name)
# return response immediately
return Response(serializer.data, status=status.HTTP_201_CREATED)
在你的tasks.py文件中修改:
@shared_task
def upload_image_background_task(archive_id, image_data, image_name):
try:
archive = Archive.objects.get(pk=archive_id)
# save the image file in the background
archive.file.save(image_name, ContentFile(image_data))
# save the instance to finalize changes
archive.save()
except Archive.DoesNotExist:
pass # handle the case where the instance might not exist