如何在Flask中用WTForms的MultipleFileField限制上传文件数量
解决方案
一、jQuery 前端限制上传文件数量
直接通过监听文件选择框的事件,实时校验选中文件数量,超出限制时给出提示并拦截:
$(document).ready(function() { // 自定义允许上传的最大文件数 const MAX_UPLOAD_COUNT = 3; // 监听文件选择事件 $('input[type="file"][name="field"]').on('change', function() { const selectedFiles = this.files; if (selectedFiles.length > MAX_UPLOAD_COUNT) { alert(`最多只能上传 ${MAX_UPLOAD_COUNT} 个文件`); // 清空已选文件,避免超出数量的文件被提交 $(this).val(''); } }); // 表单提交前二次校验,防止绕过前端限制 $('form').on('submit', function(e) { const selectedFiles = $('input[type="file"][name="field"]')[0].files; if (selectedFiles.length > MAX_UPLOAD_COUNT) { alert(`最多只能上传 ${MAX_UPLOAD_COUNT} 个文件`); e.preventDefault(); return false; } }); });
二、已上传文件列表展示与删除功能
需要前后端配合实现文件记录存储、页面渲染和删除交互:
1. 后端逻辑(存储与删除接口)
将已上传文件信息存在会话中(或数据库,根据实际需求选择),同时提供删除接口:
from flask import Flask, render_template, request, session, jsonify from werkzeug.utils import secure_filename import os from your_form_module import NameForm app = Flask(__name__) app.secret_key = 'your_secret_key_here' UPLOAD_DIR = 'uploads' os.makedirs(UPLOAD_DIR, exist_ok=True) # 文件上传处理 @app.route('/upload', methods=['GET', 'POST']) def upload_file(): form = NameForm() if form.validate_on_submit(): uploaded_files = form.field.data # 初始化会话中的文件列表 if 'uploaded_files' not in session: session['uploaded_files'] = [] # 保存文件并记录文件名 for file in uploaded_files: safe_name = secure_filename(file.filename) file.save(os.path.join(UPLOAD_DIR, safe_name)) session['uploaded_files'].append(safe_name) session.modified = True return render_template('upload_page.html', form=form) # 文件删除接口 @app.route('/remove-file', methods=['POST']) def remove_file(): target_file = request.json.get('filename') if target_file and 'uploaded_files' in session and target_file in session['uploaded_files']: # 删除服务器上的文件 file_path = os.path.join(UPLOAD_DIR, target_file) if os.path.exists(file_path): os.remove(file_path) # 从会话中移除记录 session['uploaded_files'].remove(target_file) session.modified = True return jsonify({'success': True}) return jsonify({'success': False})
2. 前端模板(列表渲染与删除交互)
在页面中渲染已上传文件列表,给每个文件绑定删除按钮的AJAX事件:
<form method="POST" enctype="multipart/form-data"> {{ form.hidden_tag() }} {{ form.field.label }} {{ form.field() }} <button type="submit">上传文件</button> </form> <!-- 已上传文件列表 --> {% if 'uploaded_files' in session and session['uploaded_files'] %} <h3>已上传文件</h3> <ul id="file-list"> {% for filename in session['uploaded_files'] %} <li> {{ filename }} <button class="delete-btn" data-file="{{ filename }}">删除</button> </li> {% endfor %} </ul> {% endif %} <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> // 前面的文件数量校验代码... // 文件删除逻辑 $('.delete-btn').on('click', function() { const filename = $(this).data('file'); if (confirm(`确定删除 ${filename} 吗?`)) { $.ajax({ url: '/remove-file', method: 'POST', contentType: 'application/json', data: JSON.stringify({filename: filename}), success: function(res) { if (res.success) { // 移除页面上的对应文件项 $(`button[data-file="${filename}"]`).parent('li').remove(); } else { alert('删除失败,请重试'); } }, error: function() { alert('请求出错,删除失败'); } }); } }); </script>
三、后端兜底验证(必加)
前端校验可被绕过,必须在FlaskForm中添加后端验证器确保限制生效:
from flask_wtf import FlaskForm from wtforms import MultipleFileField from wtforms.validators import ValidationError def max_file_count(max_num): def validator(form, field): if len(field.data) > max_num: raise ValidationError(f"最多允许上传 {max_num} 个文件") return validator class NameForm(FlaskForm): field = MultipleFileField('fieldname', validators= [max_file_count(3)])
内容的提问来源于stack exchange,提问作者Lorchis
相关产品推荐
相关产品推荐

