Flask 第十二话之文件上传
一、上传文件注意事项
1.在html中form必须带有`enctype="multipart/form-data"`属性才能上传文件
2.在后台获取上传文件:request.files.get('input name属性值')
3.保存文件前导入from werkzeug.utils import secure_filename,使用secure_filename过滤文件名排除文件名为:"../../.bash"等的安全隐患
4.获取上传文件后使用save方法来保存文件
示例代码:
1.html
<form action="" method="post" enctype="multipart/form-data"> <table> <tbody> <tr> <td>头像:</td> <td><input type="file" value="" name="avatar"></td> </tr> <tr> <td>描述:</td> <td><input type="text" value="" name="desc"></td> </tr> <tr> <td></td> <td><input type="submit" value="提交"></td> </tr> </tbody> </table> </form>
2.app.py
注:UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'文件夹路径') ==> UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'static/images')
from werkzeug.utils import secure_filename import os UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'images') # 上传文件 @app.route('/',methods=["GET","POST"]) def upload(): if request.method == "GET": return render_template('upload.html') else: avatar = request.files.get('avatar') desc = request.form.get('desc') # 去除上传得安全隐患:例如文件名为:../../user/xx.zip filename = secure_filename(avatar.filename) avatar.save(os.path.join(UPLOAD_PATH,filename)) return 'ok'
二、获取文件
注:需要导入from flask import send_from_directory,使用send_from_directory返回文件路径及文件名
实例代码:
1.html
<img src="{{ url_for("get_images",filename="20200306163522.jpg") }}" alt="">
2.app.py
# 获取文件:http://127.0.0.1:5000/images/4.png from flask import send_from_directory @app.route('/images/<filename>') def get_images(filename): return send_from_directory(UPLOAD_PATH,filename)
三、使用flask-wtf处理文件上传
1.forms.py
注:导入from flask_wtf.file import FileAllowed,FileRequired 使用FileAllowed验证什么文件类型可以通过
from wtforms import Form,FileField,StringField from wtforms.validators import InputRequired # flask_wtf from flask_wtf.file import FileAllowed,FileRequired class UploadForm(Form): avatar = FileField(validators=[ FileRequired(), FileAllowed([ 'jpg', 'png', 'gif' ]) ]) desc = StringField(validators=[ InputRequired() ])
2.app.py
注:需要导入from werkzeug.datastructures import CombinedMultiDict,将request.form和request.files共同放入到forms中进行验证
from flask import Flask,render_template,request from werkzeug.utils import secure_filename import os UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'images') from forms import UploadForm from werkzeug.datastructures import CombinedMultiDict # 上传文件 @app.route('/',methods=["GET","POST"]) def upload(): if request.method == "GET": return render_template('upload.html') else: # 使form同时接收request.form, request.files form = UploadForm(CombinedMultiDict( [request.form, request.files] )) if form.validate(): avatar = request.files.get('avatar') desc = request.form.get('desc') # 去除上传得安全隐患:例如文件名为:../../user/xx.zip filename = secure_filename(avatar.filename) avatar.save(os.path.join(UPLOAD_PATH,filename)) return 'ok' else: print(form.errors) return 'filed'
3.html
<form action="" method="post" enctype="multipart/form-data"> <table> <tbody> <tr> <td>头像:</td> <td><input type="file" value="" name="avatar"></td> </tr> <tr> <td>描述:</td> <td><input type="text" value="" name="desc"></td> </tr> <tr> <td></td> <td><input type="submit" value="提交"></td> </tr> </tbody> </table> </form>