在Django Rest框架中上传临时文件

问题描述

我正在尝试创建一种上传xlsx文件然后使用celery执行某些操作的方法。

我在想:

  • 用于上传文件并临时保存文件的视图
  • 使用celery执行我想要的文件,然后将其删除。

我正在尝试做这样的事情:

class ImportMyFileView(APIView):
    parser_classes = (FileUploadParser,)

    def post(self,request,filename,format=None):
        my_file = request.data["file"]
        with open(f"/tmp/{my_file.name}","wb+") as destination:
            for chunk in my_file.chunks():
                destination.write(chunk)
        # call_celery_here()
        ...
        Return something

我可以在所需的位置生成文件,但是问题是当我打开xlsx时。我在这里得到这个:

--X-INSOMNIA-BOUNDARY
Content-Disposition: form-data
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

PK<q^Q_rels/.rels���J1��}��{w�Dd���ЛH}���a7�0u}{�Z���I~��7C��f�G�Fo�Z+���{�����kW�#�VJ$cʪ��l� �n�0�\Q�X^:�`���d�d{�m]_�d����h��V����F�w�^F9��W��-�(F/3�O�DSU�N�l/w�{N(�[��q��T����u<��r�?焮�s9�F����M��h���'h?PKf����

是否缺少任何细节?

解决方法

这是我要依靠DRF的内置功能来实现的方式:

import os

from rest_framework import serializers
from django.core.files.storage import FileSystemStorage

class UploadSerializer(serializers.Serializer):
    file = serializers.FileField()

class UploadView(APIView):
    ...
    def post(self,request):
        ser = UploadSerializer(request.data)
        ser.is_valid(raise_exception=True)

        fs = FileSystemStorage(tempfile.gettempdir())
        file_name = fs.save(content=ser.validated_data['file'])
        full_path = os.path.join(fs.location,file_name)

        celery_func.delay(file_name=full_path)
        return Response("Upload OK")

执行此操作的更可靠的方法是创建一个表示要处理的上载的模型,并使用the django model's FileField

class Todo(models.Model):
   xlsx_file = models.FileField(...) # read the docs on this
   created_at = models.DateTimeField(auto_now_add=True)
   is_complete = models.BooleanField(default=False)

class UploadView(APIView):
    def post(self,request):
       ...
       todo = Todo.objects.create(
           xslx_file = ser.validated_data['file']
       )
       celery_func.delay(todo_id=todo.pk)
       return Response("Upload OK")

一旦成功,您可以单独使用ModelSerializer或与ModelViewSet配对使用。不过那是更大的学习曲线。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...