上传文件,需要使用到html
的input
控件,其type
为file
。Boostrap
提供了一个美观且功能强大上传控件,样式如下:
它提供文件的预览,并且自带remove
和upload
按钮。要使用这个控件,需要再额外引入相应的js
和css
文件,如下:
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap-fileinput/4.4.6/css/fileinput.min.css"/>
<script src="https://cdn.bootcss.com/bootstrap-fileinput/4.4.6/js/fileinput.min.js"></script>
上传控件的html
代码如下:
<form class="avatar-input-form" method="POST" enctype="multipart/form-data">
<input name="avatar_upload" type="file" class="file" data-show-preview="false"/>
</form>
我把data-show-preview
设置为false
,关闭了上传文件的预览,更多关于这个控件的内容可以自行搜索。
此时修改头像的页面是这样的,我们先完成功能,后续再美化。
那么如何获取上传的文件呢,与获取POST
数据类似(上传文件其实也是使用POST
方法),在flask
中使用request.files[name]
获取上传的文件,其中name
为对应input
控件的name
值(name="avatar_upload"
),然后使用文件的save
方法即可保存。例如:
@app.route('/user/avatar/', methods=['GET', 'POST'])
def avatar():
if request.method == 'GET':
return render_template('avatar.html')
else:
file = request.files['avatar_upload']
path = "D:\\Flask\\HarpQA\\static\\"
file.save(path + file.filename)
return 'Saved'
注意save
方法要加上具体的路径,默认不会保存到py
文件所在的路径,而是系统的根目录,此时会提示Permission denied
。我们接下来要把上传的文件设置为用户的新头像,其实可以直接将user
的avatar_path
修改为上传文件的路径,这样整个功能就完成了,但为了规范,我们建立一个文件夹专门存放头像文件(static/images/uploads
),并且以用户id
来命名文件,这样就避免出现文件名重复导致被覆盖。修改视图函数,如下:
@app.route('/user/avatar/', methods=['GET', 'POST'])
def avatar():
if request.method == 'POST':
file = request.files['avatar_upload']
base_path = path.abspath(path.dirname(__file__))
filename = str(g.user.id) + '.' + file.filename.rsplit('.', 1)[1]
file_path = path.join(base_path, 'static', 'images', 'uploads', filename)
file.save(file_path)
g.user.avatar_path = 'images/uploads/' + filename
db.session.commit()
return render_template('avatar.html')
这里用了os
库的path
来处理路径相关的东西。随便浏览个本地图片并上传,效果如下:
此时文件已经上传到了uploads
文件夹:
数据图中的avatar_path
也更新了:
此外,我们还可以添加上传文件大小限制,安全限制等更多的功能,在此就不演示了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。