版权声明:请附链接,自由转载 https://blog.csdn.net/kangkanglou/article/details/79036388
在Flask Web开发入门(八)之文件上传中,我们探讨了Flask框架下的文件上传,本章我们将使用Flask插件Flask-Uploads示例说明的图片上传与展现如何实现
开始之前,我们先简单看下Flask-Uploads源码实现:
类UploadSet:
文件上传配置集合,包含三个参数:
- name:文件上传配置集合的名称,默认files,一般不用修改,只是一个标识,要求数字、字母或两者组合,满足isalnum
- extensions:上传文件类型,默认DEFAULTS = TEXT + DOCUMENTS + IMAGES + DATA,包含文本、文档、图片、CSV、INI、YML等配置文件
- default_dest:上传文件的默认存储路径,我们可以通过app.config[‘UPLOADS_DEFAULT_DEST’]来指定
方法configure_uploads
应用配置好之后,调用此方法,扫描上传配置选项并保存到我们的应用中,注册上传模块。
方法resolve_conflict
解决名字重复问题,如果服务器上已经存在指定文件名的文件,那么Flask-Uploads通过此方法解决文件保存时的冲突问题,解决策略:文件名后加_num,num从1开始,之后拿新的名字重新判断是否存在,如果仍旧存在,再次加1,直至不存在为止
方法实现:
name, ext = os.path.splitext(basename)
count = 0
while True:
count = count + 1
newname = '%s_%d%s' % (name, count, ext)
if not os.path.exists(os.path.join(target_folder, newname)):
return newname
方法调用:
if os.path.exists(os.path.join(target_folder, basename)):
basename = self.resolve_conflict(target_folder, basename)
示例
简单分析完Flask-Uploads源码实现之后,我们来看下如何通过Flask-Uploads实现图片上传与展现
- 定义基本配置与应用注册
app.config['UPLOADS_DEFAULT_DEST'] = UPLOAD_PATH
app.config['UPLOADS_DEFAULT_URL'] = 'http://127.0.0.1:9000/'
uploaded_photos = UploadSet()
configure_uploads(app, uploaded_photos)
- 上传处理逻辑
# http://flask-uploads.readthedocs.io/en/latest/
@app.route('/flask-upload', methods=['POST'])
def flask_upload():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
logger.debug('No file part')
return jsonify({'code': -1, 'filename': '', 'msg': 'No file part'})
file = request.files['file']
# if user does not select file, browser also submit a empty part without filename
if file.filename == '':
logger.debug('No selected file')
return jsonify({'code': -1, 'filename': '', 'msg': 'No selected file'})
else:
try:
filename = uploaded_photos.save(file)
logger.debug('%s url is %s' % (filename, uploaded_photos.url(filename)))
return jsonify({'code': 0, 'filename': filename, 'msg': uploaded_photos.url(filename)})
except Exception as e:
logger.debug('upload file exception: %s' % e)
return jsonify({'code': -1, 'filename': '', 'msg': 'Error occurred'})
else:
return jsonify({'code': -1, 'filename': '', 'msg': 'Method not allowed'})
注意:核心方法即:uploaded_photos.save(file)
- 前台代码
var photoUpload = upload.render({
elem: '#btn_photo'
, url: '/flask-upload'
, exts: 'jpg|png|jpeg'
, size: 5120
, before: function (obj) {
obj.preview(function (index, file, result) {
$('#photo').attr('src', result);
$('#photo').css('width', '300');
$('#photo').css('height', '300');
});
}
, done: function (res) {
if (res.code == 0) {
layer.msg(res.filename + '上传成功!');
var href = '<a href="' + res.msg + '" style="color:blue; text-decoration: solid;">' + res.msg + '</a>'
$('#txt_photo').html(href)
} else {
return layer.msg('上传失败');
}
}
, error: function () {
var photo = $('#txt_photo');
photo.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-mini demo-reload">重试</a>');
photo.find('#btn_photo').on('click', function () {
photoUpload.upload();
});
}
});
- 实现效果
注意红色框内的文件名,我连续上传了三次,那么第三次文件名后面家了_2