Путь к файлу не сохраняется в базе данных, но находится в хранилище. Коллизия? Фреймворк для отдыха Django

Эй, я пытаюсь обработать загрузку файлов с помощью задач celery. Однако после выполнения всех задач файл оказывается в хранилище, а не в базе данных, когда я запрашиваю /files. Эскиз (который генерируется как вторая задача, но гораздо быстрее) сохраняется и в хранилище, и в базе данных. В чем может быть проблема?

views.py

@extend_schema(
        description="Upload file",
        request=FileSerializer,
        responses={201: FileSerializer},
    )
    def post(self, request, *args, **kwargs):

        file = request.data["file"]

        total_sum = File.objects.filter(owner=request.user).aggregate(models.Sum("size"))
        total_sum = total_sum["size__sum"] if total_sum["size__sum"] else 0

        if total_sum + file.size > request.user.storage_limit:
            return Response(
                {"error": "Storage limit exceeded"}, status=status.HTTP_400_BAD_REQUEST
            )

        request.data["size"] = file.size

        serializer = FileSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save(owner=request.user, size=file.size)
            FileService.upload_file(serializer.data["id"], file.read(), file.content_type)

            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

services.py

import base64
import mimetypes
from common.service import Service
from storage.tasks import UploadHandler, ThumbnailHandler


class FileService(Service):  # Service is empty class, just class Service: ...
    handlers = [UploadHandler, ThumbnailHandler]
    handler = handlers[0]()
    for next_handler in handlers[1:]:
        handler.set_next(next_handler())

    @staticmethod
    def get_file_extension(mimetype: str):
        return mimetypes.guess_extension(mimetype)

    @staticmethod
    def upload_file(file_id: str, file: bytes, mimetype: str):
        file_bytes = base64.b64encode(file)
        extension = FileService.get_file_extension(mimetype)

        FileService.handler.handle((file_id, extension, file_bytes))

tasks.py

import base64

from celery import shared_task
from django.conf import settings
from django.core.files.base import ContentFile
from services.grpc_client import Client
from common.chain import AbstractHandler
from storage.models import File


def next_status(file: File):
    file.status += 1
    file.save()


def update_file_status(func):
    def wrapper(self, request):
        file_id, *args = request

        file_object = File.objects.get(id=file_id)

        next_status(file_object)
        return func(self, request)

    return wrapper


class UploadAbstractHandler(AbstractHandler):
    @staticmethod
    def get_file(file_id: str):
        return File.objects.get(id=file_id)

    @staticmethod
    def get_file_data(content: bytes, decode=False):
        if decode:
            content = base64.b64decode(content.decode(encoding="utf-8"))

        file_data = ContentFile(content)
        return file_data


class UploadHandler(UploadAbstractHandler):
    @staticmethod
    @shared_task
    def handle_file_upload(file_id: str, extension: str, content: bytes):
        file = UploadAbstractHandler.get_file(file_id)

        file_data = UploadAbstractHandler.get_file_data(content, decode=True)
        file.file.save(f"{file.id}.{extension}", file_data)

    @update_file_status
    def handle(self, request):
        file_id, extension, content = request

        self.handle_file_upload.delay(file_id, extension, content)
        return super().handle(request)


class ThumbnailHandler(UploadAbstractHandler):
    @staticmethod
    @shared_task
    def handle_thumbnail_generation(file_id: str, content: bytes):
        file = UploadAbstractHandler.get_file(file_id)
        file_data = UploadAbstractHandler.get_file_data(content, decode=True)

        try:
            value = Client(settings.GRPC_ADDR).generate_thumbnail(file_data.read())

            file_data = UploadAbstractHandler.get_file_data(value, decode=False)

            file.thumbnail.save(f"{file.id}_thumb.png", file_data)
        except Exception as e:
            print(e)

    @update_file_status
    def handle(self, request):
        file_id, _, content = request
        self.handle_thumbnail_generation.delay(file_id, content)
        return super().handle(request)
Вернуться на верх