如何在Django服务器中访问Postman上传的请求文件数组字段?
问题描述
- 用Postman向Django服务器发送4个文件,目标是获取每个文件的路径名、文件大小等信息。
- 服务器接收到的请求中,body里的
files字段对应一个InMemoryUploadedFile对象数组:
[<InMemoryUploadedFile: Screen Shot 2022-09-11 at 10.14.05 PM.png (image/png)>, <InMemoryUploadedFile: Screen Shot 2022-09-11 at 10.14.04 PM.png (image/png)>, <InMemoryUploadedFile: Screen Shot 2022-09-11 at 10.13.51 PM.png (image/png)>, <InMemoryUploadedFile: Screen Shot 2022-09-11 at 10.13.48 PM.png (image/png)>]
- 处理文件上传的Django代码如下:
import io import json from operator import itemgetter import os from django.http import Http404,HttpResponse from django.shortcuts import render from rest_framework.views import APIView from rest_framework.parsers import JSONParser from django.views.decorators.csrf import csrf_exempt from google.cloud import storage os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/Users/gabrieltorion/downloads/filestoragehelpusdefend-3082732cedb4.json" class uploadFiles(APIView): payLoad = None print("Will listen for new file uploads") bucketMemoryMax = 400_000_000_000_00 @csrf_exempt def post(self, request): storageClient = storage.Client() if request.data['name'] == 'uploadFiles': print("request.data: ", request.data) #the screen shots are in 'files' businessId, files = itemgetter("businessId", "files")(request.data) userBucket = storageClient.get_bucket(businessId) currentMemoryStorage = 0 if userBucket: blobs = storageClient.list_blobs(businessId) if blobs: for blob in blobs: currentMemoryStorage+=blob.size if currentMemoryStorage < self.bucketMemoryMax: # Get the length of the files pass else: return HttpResponse("Bucket is FULL. CANNOT UPLOAD FILES.", status=404) return HttpResponse("Post request is received.")
- 尝试两种访问方式均未达到预期:
- 使用
print(files.file)仅得到<_io.BytesIO object at 0x10b33c590> - 使用
print(files)仅得到数组里最后一个文件的文件名:Screen Shot 2022-09-11 at 10.13.48 PM.png
- 使用
请问哪里操作有误?该如何正确访问所有文件并获取它们的路径名?
问题原因与解决方法
问题原因
当通过同一个字段名(此处为files)上传多个文件时,Django REST Framework的request.data只会保留最后一个文件,而非将所有文件封装为数组。因此你通过itemgetter获取的files只是单个文件对象,并非预期的文件数组。
解决方法
要获取所有上传的文件,需使用request.FILES.getlist('files')方法,该方法会返回对应字段下所有文件对象组成的列表。
修改后的代码示例
在post方法中替换文件获取逻辑:
@csrf_exempt def post(self, request): storageClient = storage.Client() if request.data['name'] == 'uploadFiles': print("request.data: ", request.data) # 获取businessId和所有上传文件 businessId = request.data.get('businessId') files = request.FILES.getlist('files') # 用getlist获取全部文件 userBucket = storageClient.get_bucket(businessId) currentMemoryStorage = 0 if userBucket: blobs = storageClient.list_blobs(businessId) # 直接遍历blobs即可,无需额外判断 for blob in blobs: currentMemoryStorage += blob.size if currentMemoryStorage < self.bucketMemoryMax: # 遍历所有文件,逐个获取信息 for file in files: print(f"文件名: {file.name}") print(f"文件大小: {file.size} bytes") print(f"文件类型: {file.content_type}") # 若需读取文件内容,可使用file.read(),读取后需用file.seek(0)重置指针 else: return HttpResponse("Bucket is FULL. CANNOT UPLOAD FILES.", status=404) return HttpResponse("Post request is received.")
关键说明
InMemoryUploadedFile对象的常用属性:
name: 上传文件的原始文件名(即你需要的路径名/文件名)size: 文件大小(单位:字节)content_type: 文件的MIME类型(如image/png)file: 底层的BytesIO对象,用于读取文件内容
内容的提问来源于stack exchange,提问作者Gabe T
相关产品推荐
相关产品推荐

