Загрузка файла в фоновом процессе в django drf (получаем эту ошибку : Объект типа TemporaryUploadedFile не является JSON сериализуемым)
вот моя функция создания:
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
но при попытке добавить объект и загрузить файл получаем эту ошибку: Object of type TemporaryUploadedFile is not JSON serializable
запросить загрузить файл в фоновом режиме, но получить эту ошибку: «Object of type TemporaryUploadedFile is not JSON serializable»
Ошибка возникает потому, что 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