Django Form通过Bootstrap Modal上传文件时request.FILES为空如何解决
问题原因
- 页面元素ID重复:你渲染后的页面存在两个id为
id_file的文件上传控件,分别属于普通表单和模态框表单。HTML规范要求元素id全局唯一,浏览器处理表单提交时会优先匹配第一个出现的同id控件,也就是普通表单中未选择文件的输入框,导致模态框提交时实际没有传递选中的文件数据,所以request.FILES为空。 - 视图代码存在隐藏bug:
file_form.is_valid是方法,调用时没有加括号,判断逻辑永远为真,不符合表单校验要求。 - 模态框表单的
action属性写法不规范:.?&status=status-update中问号后多余了&符号,虽然不影响文件上传,但建议修正为.?status=status-update。
解决方法
- 规避id重复问题:给模态框使用的表单实例指定独立前缀,Django会自动生成不重复的控件id和name,修改视图代码如下:
def index(request): if request.method == "POST": # 区分普通表单和模态框表单的提交 if 'status' in request.GET: # 模态框表单提交,加对应前缀 file_form = FileForm(request.POST, request.FILES, prefix='modal') else: # 普通表单提交 file_form = FileForm(request.POST, request.FILES) print(request.POST) print(request.FILES) # 修正is_valid调用 if file_form.is_valid(): file_form.save() return redirect('/upload_file/') # 实例化两个表单,分别给普通页面和模态框使用 file_form = FileForm() modal_file_form = FileForm(prefix='modal') return render(request, 'upload_file/index.html', { 'file_form': file_form, 'modal_file_form': modal_file_form, })
然后修改模板中模态框部分的表单渲染代码,把{{ file_form.as_p }}替换为{{ modal_file_form.as_p }}即可。
- 如果不想改视图逻辑,也可以手动编写模态框内的表单控件,手动指定不重复的id和name属性,保证和普通表单的控件不冲突。
内容的提问来源于stack exchange,提问作者shun
相关产品推荐
相关产品推荐

