文件上传
- 在模板中,form表单中,需要指定encotype='multipart/form-data’才能上传。
- 在后台如果想要获取上传文件,那么应该使用request.files.get(‘avatar’)来获取。
- 保存文件之前,先要使用werkzeug.utils.secure_filename来对上传文件名进行一个过滤。这样才能保证不会有安全问题。
- 获取到上传上来的文件后,使用avatar.save(路径)方法来保存文件。
- 从服务器上读取文件,应该定义一个url与视图函数,来获取指定的文件。在这个视图函数中,使用send_form_directory(文件的目录, 文件名)来获取。
定义一个主文件:
from flask import Flask,request, render_template
import os
from werkzeug.utils import secure_filename
app = Flask(__name__)
@app.route('/')
def index():
return "首页"
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
if request.method == 'GET':
return render_template('upload.html')
else:
desc = request.form.get('desc')
image_file = request.files.get('image_file')
# print(image_file)
# print(type(image_file))
# image_file.filename文件的名字
# image_file.save(os.path.join('images', image_file.filename))
# 导入secure_filename使其名字发生变化
filename = secure_filename(image_file.filename)
image_file.save(os.path.join('images',filename ))
return "文件上传成功"
if __name__ == '__main__':
app.run(debug=True)
转化路由,定义html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>头像</td>
<td><input type="file" name="image_file"></td>
</tr>
<tr>
<td>描述</td>
<td><input type="text" name="desc"></td>
</tr>
<tr>
<td><input type="submit" value="上传" ></td>
</tr>
</table>
</form>
</body>
</html>
上传文件操作,html文件放在templates文件夹中,新建一个文件夹images,将保存的文件放到里面。
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
if request.method == 'GET':
return render_template('upload.html')
else:
desc = request.form.get('desc')
image_file = request.files.get('image_file')
# print(image_file)
# print(type(image_file))
# image_file.filename文件的名字
# image_file.save(os.path.join('images', image_file.filename))
# 导入secure_filename使其名字发生变化
filename = secure_filename(image_file.filename)
image_file.save(os.path.join('images',filename ))
return "文件上传成功"
验证和指定上传文件的类型
建立一个forms表单:
from wtforms import Form, FileField, StringField
from wtforms.validators import InputRequired
from flask_wtf.file import FileAllowed, FileRequired
class UploadForm(Form):
# FileField 文件必须上传
# FileAllowed 允许上传的类型
image_file = FileField(validators=[FileRequired(), FileAllowed(['jpg', 'png', 'gif'])])
desc = StringField(validators=[InputRequired()])
然后主文件下修改为:
from forms import UploadForm
from werkzeug.datastructures import CombinedMultiDict
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
if request.method == 'GET':
return render_template('upload.html')
else:
form = UploadForm(CombinedMultiDict([request.form, request.files]))
if form.validate():
# desc = request.form.get('desc')
# image_file = request.files.get('image_file')
# 可以改写成:
desc = form.desc.data
image_file = form.image_file.data
filename = secure_filename(image_file.filename)
image_file.save(os.path.join('images', filename))
return "文件上传成功"
else:
print(form.errors)
return "fail"
对上传文件使用表单验证
- 定义表单的时候,对文件的字段,需要采用FileField这个类型。
- 验证器应该从flask_wtf.file中导入。flask_wtf.file.FileRequired是用来验证文件上传是否为空。flask_wtf.file.FileAllowed用来验证上传的文件的后缀名。
- 在视图函数中,使用form werkzeug.datastructures import CombinedMultiDict来把request.form与request.files来进行合并。再传给表单验证。
# 访问资源下的图片
@app.route('/images/<filename>')
def get_image(filename):
return send_from_directory('images', filename)