场景:
- 点击上传文件按钮,选择需要上传的文件后上传
- 文件上传成功后,会将文件保存到指定目录下
- 限制上传文件的格式
- 在前端点击文件后下载
- 基于上述上传并保存到指定目录下的文件
上手
文件上传
app.py
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
# 渲染文件
return render_template('upload.html')
# 文件保存的目录,根据实际情况的文件结构做调整;
# 若不指定目录,可以写成f.save(f.filename),可以默认保存到当前文件夹下的根目录
# 设置上传文件保存路径 可以是指定绝对路径,也可以是相对路径(测试过)
app.config['UPLOAD_FOLDER'] = './upload'
# 将地址赋值给变量
file_dir = app.config['UPLOAD_FOLDER']
@app.route('/uploader', methods=['GET', 'POST'])
def uploader():
"""
文件上传
"""
if request.method == 'POST':
# input标签中的name的属性值
f = request.files['file']
# 拼接地址,上传地址,f.filename:直接获取文件名
f.save(os.path.join(app.config['UPLOAD_FOLDER'], f.filename))
# 输出上传的文件名
print(request.files, f.filename)
return '文件上传成功!'
else:
return render_template('upload.html')
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传</title>
<style>
a{
text-decoration: none;
color: #2062e0;
}
a:hover{
text-decoration: none;
color: #2062e0;
}
</style>
</head>
<body>
<h1 align="center">TEST</h1>
<div align="center">
{# enctype:属性用于指定将上传文件数据发送给服务器端之前对表单数据进行编码的斱式 #}
{# enctype="multipart/form-data" => 表示不对字符编码。当使用有文件上传控件的表单时,该值是必需的。 #}
<form action="/uploader" method="post" enctype="multipart/form-data">
<br><br><br>
{# accept可以自定以文件上传格式 #}
<input type="file" name="file" accept=".txt, .pdf, .doc, .docx, .md" value="{{ csrf_token }}" />
<br><br><br>
<input type="submit" value="提交" />
</form>
<br><br><br>
</div>
</body>
</html>
文件下载
app.py
@app.route('/download', methods=['GET', 'POST'])
def download():
"""
文件下载
:return:
"""
timelist = [] # 获取指定文件夹下文件并显示
Foder_Name = [] # 文件夹下所有文件
Files_Name = [] # 文件名
# 获取到指定文件夹下所有文件
lists = os.listdir(file_dir + '/')
# 遍历文件夹下所有文件
for i in lists:
# os.path.getatime => 获取对指定路径的最后访问时间
timelist.append(time.ctime(os.path.getatime(file_dir + '/' + i)))
# 遍历文件夹下的所有文件
for k in range(len(lists)):
# 单显示文件名
Files_Name.append(lists[k])
# 获取文件名以及时间信息
Foder_Name.append(lists[k] + " ~~~~~~~~~~~~~~~~~~~~~ " + timelist[k])
print(file_dir) # ./upload
return render_template('download.html', allname=Foder_Name, name=Files_Name)
@app.route('/downloads/<path:path>', methods=['GET', 'POST'])
def downloads(path):
"""
重写download方法,根据前端点击的文件传送过来的path,下载文件
send_from_directory:用于下载文件
flask.send_from_directory(所有文件的存储目录,相对于要下载的目录的文件名,as_attachment:设置为True是否要发送带有标题的文件)
:param path:
:return:
"""
return send_from_directory(app.config['UPLOAD_FOLDER'], path, as_attachment=True)
download.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
<style>
a{
text-decoration: none;
color: #2062e0;
}
a:hover{
text-decoration: none;
color: #2062e0;
}
</style>
</head>
<body>
<div align="center">
<h1>文件下载</h1><br><br>
{# 输出文件名及文件详细信息(文件时间信息等) #}
{% for fruit in allname %}
<br>
{{ fruit }}
{% endfor %}
<br><br><br><br>
{# 将指定文件夹中的文件获取遍历显示 #}
{% for n in name %}
<a href="downloads/{{ n }}">{{ n }}</a>
<br><br>
{% endfor %}
</div>
</body>
</html>
运行
- 文件上传和下载的视图函数代码都完成后,开始运行项目
app.py(在编写好试图代码的最下方编写运行代码)
"""
运行项目
"""
if __name__ == '__main__':
# 可以使统一局域网下的其他电脑访问该项目
HOST = '0.0.0.0'
# debug=True => 打开调试模式,在对代码进行修改后,可以实时运行代码
app.run(host=HOST, debug=True)
- 打开调试模式后,运行项目建议在Pycharm中的Terminal命令行中输入以下运行
python app.py
整个app.py代码
import os
import time
from flask import Flask, render_template, request, send_from_directory
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
# 渲染文件
return render_template('upload.html')
# 文件保存的目录,根据实际情况的文件结构做调整;
# 若不指定目录,可以写成f.save(f.filename),可以默认保存到当前文件夹下的根目录
# 设置上传文件保存路径 可以是指定绝对路径,也可以是相对路径(测试过)
app.config['UPLOAD_FOLDER'] = './upload' ## 该目录需要自行创建
# 将地址赋值给变量
file_dir = app.config['UPLOAD_FOLDER']
@app.route('/uploader', methods=['GET', 'POST'])
def uploader():
""" 文件上传 """
if request.method == 'POST':
# input标签中的name的属性值
f = request.files['file']
# 拼接地址,上传地址,f.filename:直接获取文件名
f.save(os.path.join(app.config['UPLOAD_FOLDER'], f.filename))
# 输出上传的文件名
print(request.files, f.filename)
return '文件上传成功!'
else:
return render_template('upload.html')
@app.route('/download', methods=['GET', 'POST'])
def download():
""" 文件下载 """
timelist = [] # 获取指定文件夹下文件并显示
Foder_Name = [] # 文件夹下所有文件
Files_Name = [] # 文件名
# 获取到指定文件夹下所有文件
lists = os.listdir(file_dir + '/')
# 遍历文件夹下所有文件
for i in lists:
# os.path.getatime => 获取对指定路径的最后访问时间
timelist.append(time.ctime(os.path.getatime(file_dir + '/' + i)))
# 遍历文件夹下的所有文件
for k in range(len(lists)):
# 单显示文件名
Files_Name.append(lists[k])
# 获取文件名以及时间信息
Foder_Name.append(lists[k] + " ~~~~~~~~~~~~~~~~~~~~~ " + timelist[k])
print(file_dir) # ./upload
return render_template('download.html', allname=Foder_Name, name=Files_Name)
@app.route('/downloads/<path:path>', methods=['GET', 'POST'])
def downloads(path):
""" 下载 """
"""
重写download方法,根据前端点击的文件传送过来的path,下载文件
send_from_directory:用于下载文件
flask.send_from_directory(所有文件的存储目录,相对于要下载的目录的文件名,as_attachment:设置为True是否要发送带有标题的文件)
"""
return send_from_directory(app.config['UPLOAD_FOLDER'], path, as_attachment=True)
"""
运行项目
"""
if __name__ == '__main__':
# 可以使统一局域网下的其他电脑访问该项目
HOST = '0.0.0.0'
# debug=True => 打开调试模式,在对代码进行修改后,可以实时运行代码
app.run(host=HOST, debug=True)
模板文件中代码已完整
注意
- 代码编写好后,需要在项目根目录先创建一个路径用于存放上传的文件
- 即创建upload文件夹
- 运行项目后,需要在浏览器地址后补充输入
/upload
,即可进入上传页面
- 即
http://127.0.0.1:5000/upload
,具体端口号需根据个人项目运行修改,可以在运行时看控制台
- 下载页面
项目文件目录