原生上传文件
-
添加一个模板文件
<html> <head> <title>原生文件上传</title> </head> <body> {% if img_url %} <img src="{{ img_url }}"> {% endif %} <form method="post" enctype="multipart/form-data"> #上传文件必须提交 <input type="file" name="photo" /> <input type="submit" value="上传" /> </form> </body> </html>
-
添加视图函数
@app.route('/upload/', methods=['GET', 'POST']) def upload(): img_url = None if request.method == 'POST': file = request.files.get('photo') #获取文件对象 if file and allowed_file(file.filename): # 获取文件后缀 suffix = os.path.splitext(file.filename)[1] # 生成随机文件名 filename = random_string() + suffix # 保存上传文件 file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # 构造上传的文件的访问URL img_url = url_for('uploaded', filename=filename) return render_template('upload.html', img_url=img_url)
-
相关配置及函数
# 允许上传的文件后缀 ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif']) # 配置上传文件保存位置 app.config['UPLOAD_FOLDER'] = os.getcwd() # 上传文件大小 app.config['MAX_CfONTENT_LENGTH'] = 1024 * 1024 * 8 # 判断是否是允许的文件后缀 def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS # 生成随机的字符串 def random_string(length=32): import random base_str = 'abcdefghijklmnopqrstuvwxyz1234567890' return ''.join(random.choice(base_str) for i in range(length)) # 获取上传文件 @app.route('/uploaded/<filename>') def uploaded(filename): # 安全的发送文件 return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
-
注意事项,文件上传失败时,应从哪些方面着手
1.表单的提交方法必须是POST 2.表单的enctype属性必须设置为multipart/form-data 3.上传的字段类型必须为file,并且必须有name属性 4.是否超过运行的最大尺寸 5.文件的保存位置是否有空间,是否有权限
-
生成缩略图,需要安装pillow库 pip install pillow
# 导入图片处理的类,默认PIL不支持python3.x,安装pillow后就可以了 from PIL import Image # 生成缩略图 # 1.打开文件 img = Image.open(pathname) # 2.重设尺寸 img.thumbnail((128, 128)) # 3.保存修改 img.save(pathname)
flask-uploads
-
说明:在文件上传时,提供了很大的方便,如:文件类型的过滤,校验等
-
安装:
pip install flask-uploads
-
使用:
相关配置:
# 上传文件的大小 app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8 # 上传文件的保存位置 app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd() # 创建上传对象,指定过滤的文件后缀 photos = UploadSet('photos', IMAGES) configure_uploads(app, photos) # 配置上传文件大小,默认64M,设置为None时使用MAX_CONTENT_LENGTH选项 patch_request_class(app, size=None) #去除默认设置
视图函数:
@app.route('/upload/', methods=['GET', 'POST']) def upload(): img_url = None if request.method == 'POST' and 'photo' in request.files: # 保存文件 filename = photos.save(request.files['photo']) # 获取保存文件的url img_url = photos.url(filename) return render_template('upload.html', img_url=img_url)
模板文件:同原生的文件上传upload.html
from werkzeug.utils import secure_filename#由from werkzeug import secure_filename,EileStorage改成现在的情况from werkzeug.datastructuresimport FileStorage
完整的文件上传
-
flask-uploads配置同上
-
flask-wtf配置
# 导入表单基类 from flask_wtf import FlaskForm # 导入文件上传字段及验证器 from flask_wtf.file import FileField, FileRequired, FileAllowed from wtforms import SubmitField # 上传文件表单类 class UploadForm(FlaskForm): 'srace' = FileField('头像上传', validators=[FileRequired('文件未选择'), FileAllowed(photos, message='只能上传图片文件')]) submit = SubmitField('上传')
-
视图函数:
@app.route('/upload/', methods=['GET', 'POST']) def upload(): img_url = None form = UploadForm() if form.validate_on_submit(): # 获取文件后缀 suffix = os.path.splitext(form.photo.data.filename)[1] # 生成所及文件名 filename = random_string() + suffix # 保存上传文件 photos.save(form.photo.data, name=filename) # 生成缩略图 pathname = os.path.join(app.config['UPLOADED_PHOTOS_DEST'], filename) # 打开文件 img = Image.open(pathname) # 设置尺寸 img.thumbnail((128, 128)) # 保存文件 img.save(pathname) # 获取上传文件的url img_url = photos.url(filename) return render_template('upload.html', form=form, img_url=img_url)
-
模板文件upload.html
{% extends 'bootstrap/base.html' %} {% import 'bootstrap/wtf.html' as wtf %} {% block content %} <div class="container"> {% if img_url %} <img src="{{ img_url }}" /> {% endif %} {{ wtf.quick_form(form) }} </div> {% endblock %}
代码运行过程如下:
app.py里面的代码如下:
import os
from flask import Flask,render_template,request
from flask_script import Manager
app = Flask(__name__)
#指定上传的路径
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__),'static')
#允许上传的文件名后缀
ALLOWED_EXTENSIONS = set(['png','jpg','jpeg','gif'])
#限定上传文件大小 8M
app.config['MAX_CONTENT_LENGTH'] = 8 * 1024 * 1024
manager= Manager(app)
#判断是否是允许的后缀 manba.jpg
def allow_file(filename):
return '.' in filename and filename.rsplit('.',1)[1] in ALLOWED_EXTENSIONS
print(allow_file('canglaoshi.jpg'))
#生成随机字符串
def random_string(length=16):
import random
base_str = '0987654321qwertyuiopasdfghjklzxcvbnm'
return "".join(random.choice(base_str) for i in range(length))
# import string
# source = list(string.ascii_letters)
# for index in range(0,10):
# source.append(str(index))
# print(source)
# return source
@app.route('/',methods=['GET','POST'])
def hello_world():
# request.args[] #get请求参数
# request.form[] #post 请求参数
# request.files
if request.method == 'POST':
file = request.files.get('photo')
if file and allow_file(file.filename):
#获取后缀名
surfix = os.path.splitext(file.filename)[1]
# 新的文件名
filename = random_string() + surfix
file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
# print(os.path.join(os.path.dirname(__file__),'upload'))
return render_template('index.html')
if __name__ == '__main__':
manager.run()
index.html里面的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>原生文件上传</h1>
<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="photo" />
<input type="submit" value="立即上传">
</form>
</body>
</html>
回到app.py文件,下面输入:
python app.py runserver -d -r -p 5050
回车,点击地址进入:
点击选择文件:
选中某个图片进行上传,保存到static文件里面: