赵走x博客
网站访问量:151870
首页
书籍
软件
工具
古诗词
搜索
登录
Flask 实战:41、电子邮件进阶实践
Flask 实战:40、使用事务邮件服务SendGird
Flask 实战:39、使用Flask-Mail发送电子邮件
Flask 实战:38、数据库进阶实践
Flask 实战:37、更新数据库表
Flask 实战:36、定义关系
Flask 实战:35、在视图函数里操作数据库
Flask 实战:34、数据库操作:CRUD
Flask 实战:33、使用Flask-SQLAlchemy管理数据库
Flask 实战:32、ORM魔法
Flask 实战:31、数据库的分类
Flask 实战:30、单个页面多个表单
Flask 实战:29、单个表单多个提交按钮
Flask 实战:28、使用Flask-CKEditor集成富文本编辑器
Flask 实战:27、多文件上传
Flask 实战:26、文件上传
Flask 实战:25、自定义验证器
Flask 实战:24、使用宏渲染表单
Flask 实战:23、设置错误消息语言
Flask 实战:22、处理表单数据
Flask 实战:21、使用Flask-WTF处理表单
Flask 实战:20、HTML表单
Flask 实战:19、模板进阶实践
Flask 实战:18、模板结构组织
Flask 实战:17、模板辅助工具
Flask 实战:16、模板基本用法
Flask 实战:15、HTTP进阶实践
Flask 实战:14、Flask上下文
Flask 实战:13、HTTP响应
Flask 实战:12、HTTP请求
Flask 实战:11、请求响应循环
Flask 实战:10、Flask与MVC架构
Flask 实战:9、模板与静态文件
Flask 实战:8、Flask命令
Flask 实战:7、URL与端点
Flask 实战:6、项目配置
Flask 实战:5、Flask扩展
Flask 实战:4、Python Shell
Flask 实战:3、启动开发服务器
Flask 实战:2、Hello,Flask!
Flask 实战:1、初识Flask
Flask 实战:27、多文件上传
资源编号:75878
Python Web
Flask Web开发实战:入门、进阶与原理解析
热度:86
因为Flask-WTF当前版本(0.14.2)中并未添加对多文件上传的渲染和验证支持,因此我们需要在视图函数中手动获取文件并进行验证。这种手动处理方式和我们在上一节介绍的方式效果基本相同。
因为Flask-WTF当前版本(0.14.2)中并未添加对多文件上传的渲染和验证支持,因此我们需要在视图函数中手动获取文件并进行验证。这种手动处理方式和我们在上一节介绍的方式效果基本相同。 在客户端,通过在文件上传字段(type=file)加入multiple属性,就可以开启多选: ```
``` 创建表单类时,可以直接使用WTForms提供的MultipleFileField字段实现,添加一个DataRequired验证器来确保包含文件: ``` from wtforms import MultipleFileField class MultiUploadForm(FlaskForm): photo = MultipleFileField('Upload Image', validators={DataRequired()} submit = SubmitField() ``` 表单提交时,在服务器端的程序中,对request.files属性调用getlist()方法并传入字段的name属性值会返回包含所有上传文件对象的列表。在multi_upload视图中,我们迭代这个列表,然后逐一对文件进行处理,如代码清单4-16所示。 代码清单4-16 form/app.py:处理多文件上传 ``` from flask import request, session, flash, redirect, url_for from flask_wtf.csrf import validate_csrf from wtforms import ValidationError @app.route('/multi-upload', methods=['GET', 'POST']) def multi_upload(): form = MultiUploadForm() if request.method == 'POST': filenames = [] # 验证CSRF令牌 try: validate_csrf(form.csrf_token.data) except ValidationError: flash('CSRF token error.') return redirect(url_for('multi_upload')) # 检查文件是否存在 if 'photo' not in request.files: flash('This field is required.') return redirect(url_for('multi_upload')) for f in request.files.getlist('photo'): # 检查文件类型 sif f and allowed_file(f.filename): filename = random_filename(f.filename) f.save(os.path.join( app.config['UPLOAD_PATH'], filename )) filenames.append(filename) else: flash('Invalid file type.') return redirect(url_for('multi_upload')) flash('Upload success.') session['filenames'] = filenames return redirect(url_for('show_images')) return render_template('upload.html', form=form) ``` 在请求方法为POST时,我们对上传数据进行手动验证,主要包含下面几步: 1)手动调用flask_wtf.csrf.validate_csrf验证CSRF令牌,传入表单中csrf_token隐藏字段的值。如果抛出wtforms.ValidationError异常则表明验证未通过。 2)其中if'photo'not in request.files用来确保字段中包含文件数据(相当于FileRequired验证器),如果用户没有选择文件就提交表单则request.files将为空。 3)if f用来确保文件对象存在,这里也可以检查f是否是FileStorage实例。 4)allowed_file(f.filename)调用了allowed_file()函数,传入文件名。这个函数相当于FileAllowed验证器,用来验证文件类型,返回布尔值,如代码清单所示。 ``` app.config['ALLOWED_EXTENSIONS'] = ['png', 'jpg', 'jpeg', 'gif'] ... def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] ``` 在上面的几个验证语句里,如果没有通过验证,我们使用flash()函数显示错误消息,然后重定向到multi_upload视图。 为了方便测试,我们还创建了一个临时的filenames列表,保存上传后的文件名到session中。访问[http://localhost:5000/multi-upload](http://localhost:5000/multi-upload) 打开多文件上传示例,单击按钮后可以选择多个文件,当上传的文件通过验证时,程序会重定向到show_images视图,这个视图返回的uploaded.html模板中将从session获取所有文件名,渲染出所有上传后的图片。 > 提示 顺便说一句,在新版本的Flask-WTF发布后,你就可以使用和单文件上传相同的方式处理表单。比如,我们可以使用Flask-WTF提供的MultipleFileField来创建提供Flask支持的多文件上传字段,使用相应的验证器对文件进行验证。在视图函数中,我们则可以继续使用form.validate_on_submit()来验证表单,并通过form.photo.data来获取字段的数据——包含所有上传文件对象(werkzeug.datastructures.FileStorage)的列表。 多文件上传处理通常会使用JavaScript库在客户端进行预验证,并添加进度条来优化用户体验,具体我们会在本书的第二部分学习。