问题描述
我正在尝试创建一种上传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配对使用。不过那是更大的学习曲线。