在 django 中使用相同的输入名称上传多个文件
Posted
技术标签:
【中文标题】在 django 中使用相同的输入名称上传多个文件【英文标题】:multiple files upload using same input name in django 【发布时间】:2010-10-25 11:30:21 【问题描述】:我在上传多个具有相同输入名称的文件时遇到问题:
<input type=file name="file">
<input type=file name="file">
<input type=file name="file">
在django这边
print request.FILES :
<MultiValueDict: u'file': [
<TemporaryUploadedFile: captcha_bg.jpg (image/jpeg)>,
<TemporaryUploadedFile: 001_using_git_with_django.mov (video/quicktime)>,
<TemporaryUploadedFile: ejabberd-ust.odt (application/vnd.oasis.opendocument.text)>
]>
所以所有三个文件都在一个 request.FILES['file'] object 下。我如何处理从这里上传的每个文件?
【问题讨论】:
单元素多元素的相同问题及解决方案:<input type="file" name="file" multiple />
【参考方案1】:
此代码为示例
for f in request.FILES.getlist('myfile[]'):
if request.method == 'POST' and f:
myfile = f
filesystem = FileSystemStorage()
filename = filesystem.save(myfile.name, myfile)
【讨论】:
这个答案没有意义。 'myfile[]' 是一个字符串。写 [] 不会强制它进入列表【参考方案2】:for f in request.FILES.getlist('file'):
# do something with the file f...
编辑:我知道这是一个旧答案,但我刚刚遇到它并且已经编辑了答案以使其实际上是正确的。之前建议您可以直接遍历request.FILES['file']
。要访问 MultiValueDict 中的所有项目,请使用 .getlist('file')
。仅使用 ['file']
只会返回它为该键找到的最后一个数据值。
【讨论】:
知道为什么request.FILES['file']
不起作用吗?我很好奇。
@Mark 如果你的意思是没有上传文件,它会返回一个空字符串或列表,但是如果你的意思是你上传了,但你仍然无法从request.FILES['file']
s 获取文件它是您很可能在 html 代码中的 input
字段中缺少必要的字段。根据我的经验,您需要在input field
中使用name="myfile"
来使其具体化。在这种情况下,您应该使用request.FILES['myfile']
。在 html 代码中使用 file
作为名称很难区分什么是什么。
在处理多个文件时,还有一件很重要的事情是在您的 html form
标签中包含“multiple/form-data”,因此您包装 input
标签的表单标签将是 <form method="POST" enctype="multipart/form-data">
十年后,这个答案仍然有效,谢谢!【参考方案3】:
鉴于您的 url 指向 envia,您可以像这样管理多个文件:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from django.http import HttpResponseRedirect
def envia(request):
for f in request.FILES.getlist('file'):
handle_uploaded_file(f)
return HttpResponseRedirect('/bulk/')
def handle_uploaded_file(f):
destination = open('/tmp/upload/%s'%f.name, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
【讨论】:
你不应该使用用户提供的文件名在磁盘上写,它可能被操纵在任何地方写。使用随机文件名并将原始文件名存储在数据库中仅用于演示目的【参考方案4】:我不认为所有三个文件都将位于单个 request.FILES['file']
对象下。 request.FILES['file']
可能包含该列表中的第一个文件或最后一个文件。
您需要像这样唯一地命名输入元素:
<input type=file name="file1">
<input type=file name="file2">
<input type=file name="file3">
..例如。
编辑:Justin's answer 更好!
【讨论】:
Django 会自动处理多个输入具有相同名称的情况:它会将值列表而不是单个值传递给您的代码。您可以在发布的代码中看到该列表。 那么这个 'MultiValueDict' 可能是 request.FILES['file'] 对象的包装结果? 是的,request.FILES 是 MultiValueDict 对象,而 request.GET 和 request.POST 是 QueryDict 对象,类似以上是关于在 django 中使用相同的输入名称上传多个文件的主要内容,如果未能解决你的问题,请参考以下文章