在使用Web表单时,经常会使用到上传文件功能,request.files对象可以获取与表单相关的数据。
项目的目录结构如下:
<!--upload.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
</head>
<body>
<!--form表单中设置enctype="multipart/form-data",用于上传文件-->
<form action="" method="post" enctype="multipart/form-data">
<div>
<label for="avatar">上传图片</label>
<input type="file" id="avatar" name="avatar" value="">
</div>
<button type="submit">提交</button>
</form>
</body>
</html>
@app.route('/upload',methods=['GET','POST'])
def upload():
"""
头像上传表单页面
:return:
"""
if request.method == 'POST':
# 接受头像字段
avatar = request.files['avatar']
# 判断文件是否上传,已经上传文件类型是否正确
if avatar and allowed_file(avatar.filename):
# 生成一个随机文件名
filename = random_file(avatar.filename)
# 保存文件
avatar.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',filename=filename))
return render_template('upload.html')
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
def allowed_file(filename):
"""
判断上传文件类型是否允许
:param filename: 文件名
:return: 布尔值True或False
"""
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
接下来使用random_file()函数为上传的文件重新创建一个随机的不重复的文件名,通过使用uuid.uuid4()生产处一个随机的几乎不可能重复的文件名,然后拼接一个完整的路径,代码如下所示。
import uuid
def random_file(filename):
"""
生成随机文件
:param filename: 文件名
:return: 随机文件名
"""
# 获取文件后缀
ext = os.path.splitext(filename)[1]
# 使用uuid生成随机字符
new_filename = uuid.uuid4().hex+ext
return new_filename
@app.route('/uploads/<filename>')
def uploaded_file(filename):
"""
显示上传头像
:param filename: 文件名
:return: 真实文件路径
"""
return send_from_directory(app.config['UPLOAD_FOLDER'],filename)
# run.py
import os
import uuid
from flask import send_from_directory
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
UPLOAD_FOLDER = os.path.join(app.root_path, 'uploads')
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
"""
判断上传文件类型是否允许
:param filename: 文件名
:return: 布尔值True或False
"""
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
def random_file(filename):
"""
生成随机文件
:param filename: 文件名
:return: 随机文件名
"""
# 获取文件后缀
ext = os.path.splitext(filename)[1]
# 使用uuid生成随机字符
new_filename = uuid.uuid4().hex+ext
return new_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload():
"""
头像上传表单页面
"""
if request.method == 'POST':
# 接受头像字段
avatar = request.files['avatar']
# 判断文件是否上传,已经上传文件类型是否正确
if avatar and allowed_file(avatar.filename):
# 生成一个随机文件名
filename = random_file(avatar.filename)
# 保存文件
avatar.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file', filename=filename))
return render_template('upload.html')
@app.route('/uploads/<filename>')
def uploaded_file(filename):
"""
显示上传头像
:param filename: 文件名
:return: 真实文件路径
"""
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run(debug=True)
全部评论