flask_uploads
文档:https://pythonhosted.org/Flask-Uploads/
参考:https://zhuanlan.zhihu.com/p/24418074
安装:
$ pip install flask_uploads
上传配置
下面4个设置适用于单一个的上传集(Upload Sets
),将 FILES
替换为该上传集的名称(如:PHOTOS
、ATTACHMENTS
)。
-
UPLOADED_FILES_DEST
设置上传的文件将被保存到哪个目录。 -
UPLOADED_FILES_URL
如果你有一个服务器并提供文件访问,该参数设置了公开访问的 URL。 -
UPLOADED_FILES_ALLOW
设置允许上传的文件扩展名。 -
UPLOADED_FILES_DENY
设置不允许上传的文件扩展名。
为了节省时间 flask_uploads
提供了两个参数可供我们作为“默认”参数使用,它们对所有上传集都有用:
-
UPLOADS_DEFAULT_DEST
如果你设置了该参数,那么如果一个上传集没有声明保存上传文件的路径。那么它的上传将被存储在这个目录的子目录中。
例如,如果你将此设置为/var/uploads
,那么名为photos
的上传集将把它的上传文件存储在/var/uploads/photos
。 -
UPLOADS_DEFAULT_URL
如果你设置了该参数,那么它就会作为访问服务器文件的基础 URL,例如http://localhost:5001
可以访问/var/uploads
,那么http://localhost:5001/photos
就可访问photos
的上传集上传的文件。
上传集
声明一个上传集的方法如下:
photos = UploadSet('photos', IMAGES)
然后你就可以使用 save()
方法来保存上传的文件。
filename = photos.save(request.files['photo'])
注意,这里 request.files['photo']
的 photo
属性对应的应该是前端 HTML 中的 <input type="file" name="photo">
,否则无法获取到文件。
filename
这里是一个字符串,为文件名。
上传集的方法与属性
- path
根据文件名返回文件的上传路径,该路径由 UPLOADED_FILES_DEST
属性设定。
photos.path(filename)
# 结果
./static/uploads/photos\cat.jpg
- url
根据文件名返回展示或下载该文件的网址,该网址由 UPLOADED_FILES_URL
属性设定。
photos.url(filename)
# 结果
http://127.0.0.1:5000/_uploads/photos/cat.jpg
加载上传集
上传集需要用 configure_uploads
函数加载后使用:
configure_uploads(app, photos)
patch_request_class
方法可以设定上传文件的大小限制:
# 默认大小限制为 16 M
patch_request_class(app)
# 设定限制为 32 M
patch_request_class(app, 32 * 1024 * 1024)
上传表单
HTML 上传表单需要注意几个属性的设定。method
设为 POST
,enctype
设为 multipart/form-data
。字段本身应该是一个 <input type=file>
。
<form method=POST enctype=multipart/form-data action="{{ url_for('upload') }}">
...
<input type=file name=photo>
...
</form>
完整实现
# 上传文件储存地址
app.config['UPLOADED_PHOTOS_DEST'] = './static/uploads/photos'
# 在浏览器访问文件的网址
app.config['UPLOADED_PHOTOS_URL'] = '/static/uploads/photos/'
# 允许上传的文件扩展名
app.config['UPLOADED_PHOTOS_ALLOW'] = set(['jpg'])
# 上传集
photos = UploadSet('photos', IMAGES)
# 注册上传集的配置
configure_uploads(app, photos)
# 文件大小限制,默认为16MB
patch_request_class(app)
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST' and 'photo' in request.files:
# 保存文件
filename = photos.save(request.files['photo'])
# 根据文件名获取到文件 url
return redirect(photos.url(filename))
return render_template('upload-page.html')