在学习django框架,多个文件上传时遇到ValueError: ClearableFileInput doesn't support uploading multiple files. 代码如下:
urls.py
urlpatterns = [
# path('',views.index,name='index'),
# 单个文件上传
path('upload/',views.upload,name='upload'),
# 多个文件上传
path('many_upload/',views.manyFile_upload,name='many_upload'),
]
form.py
from django import forms
class MultiFilesForm(forms.Form):
files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
views.py
def manyFile_upload(request):
if request.method == 'POST':
form = MultiFilesForm(request.POST,request.FILES)
path = settings.MEDIA_ROOT
if form.is_valid():
upload_files = request.FILES.getlist('files')
for f in upload_files:
path += f.name
with open(path,'wb') as fp:
for chunk in f.chunks():
fp.write(chunk)
else:
form = MultiFilesForm()
return render(request,'app04/upload.html',{'form':form})
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="{% url 'App04:many_upload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
文件上传:{{ form }}<br>
<input type="submit" name="上传">
</form>
</body>
</html>
调试运行,产生如下错误:
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\Users\David\PycharmProjects\day02\App04\urls.py", line 3, in <module>
from App04 import views
File "C:\Users\David\PycharmProjects\day02\App04\views.py", line 6, in <module>
from App04.forms import MultiFilesForm
File "C:\Users\David\PycharmProjects\day02\App04\forms.py", line 4, in <module>
class MultiFilesForm(forms.Form):
File "C:\Users\David\PycharmProjects\day02\App04\forms.py", line 5, in MultiFilesForm
files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\David\PycharmProjects\.venv\Lib\site-packages\django\forms\widgets.py", line 427, in __init__
raise ValueError(
ValueError: ClearableFileInput doesn't support uploading multiple files.
经过反复调试,修改代码解决问题。
1. 把前端html修改,使得上传单一文件和多文件代码 合一:
文件上传:<input type="file" name="photo" multiple="true"> 增加multiple='true'属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="{% url 'App04:upload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
文件上传:<input type="file" name="photo" multiple="true"><br>
<input type="submit" name="上传">
</form>
</body>
</html>
2.urls.py:注销掉多文件上传
# path('many_upload/',views.manyFile_upload,name='many_upload'),
app_name = 'App04'
urlpatterns = [
# path('',views.index,name='index'),
# 单个文件上传
path('upload/',views.upload,name='upload'),
# 多个文件上传
# path('many_upload/',views.manyFile_upload,name='many_upload'),
]
3.删除forms.py 文件
from django import forms
#
#
# class MultiFilesForm(forms.Form):
# files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
4.在settings配置中,上传文件存储路径:
# 上传文件路径
# MEDIA_ROOT = [
# BASE_DIR / 'static/upload'
# ] # MEADIA_ROOT 是个列表,所以传递给path就错误了。
MEDIA_ROOT = os.path.join(BASE_DIR,'static/upload')
5. view.py 代码修改
import os.path
from django.http import HttpResponse
from django.shortcuts import render
# from App04.forms import MultiFilesForm
from App04.utils import FileUpLoad
from day02 import settings
# Create your views here.
def upload(request):
if request.method == 'POST':
# 取上传文件列表
files = request.FILES.getlist('photo')
print(files, type(files))
for f in files:
# 取文件存储路径,并添加文件名。
path = os.path.join(settings.MEDIA_ROOT,f.name)
with open(path,'wb') as fp:
# 判断文件是否大于2.5Mb,如果大于,分块读写。
if f.multiple_chunks():
for chunk in f.chunks():
fp.write(chunk)
else:
fp.write(f.read())
return HttpResponse('文件上传成功')
return render(request,'app04/upload.html')
显示结果:
f