python + layui.upload 上传文件,同时提交其它字段
我的设计是点击【按钮】的时候打开弹窗,弹窗里的表单包含上传文件和其它字段。
点击弹出层的按钮:
<button class="layui-btn" id="upload_btn"><i class="layui-icon"></i>导入HAR</button>
js:
layui.use(['layer','upload','form'], function(){
var $ = layui.jquery, layer = layui.layer, upload=layui.upload;
$('#upload_btn').click( function(){
var uploadInst;
var index = layer.open({
title:'导入文件',
type: 1,
shade:0.4, ////遮罩透明度
area: ['400px', '250px'],
content: '<div id="import_har" style="margin-top: 20px;margin-left: 20px">\n' +
' <form class="layui-form layui-form-pane">\n' +
' <div class="layui-form-item">\n' +
' <label class="layui-form-label">输入框</label>\n' +
' <div class="layui-input-block">\n' +
' <input type="text" name="input_name" required lay-verify="required" placeholder="请输入..." class="layui-input" style="width: 90%">\n' +
' </div>\n' +
' </div>\n' +
' <div class="layui-form-item">\n' +
' <div class="layui-btn-container upload-file-box">\n' +
' <button type="button" class="layui-btn" id="har_file"><i class="layui-icon"></i>上传文件</button>\n' +
' </div>\n' +
' </div>\n' +
' <div>\n' +
' <div class="layui-input-block" style="text-align: right;margin-right: 20px;margin-top: 10px;">\n' +
' <button lay-submit="" type="button" class="layui-btn" id="commit">立即提交</button>\n' +
' </div>\n' +
' </div>\n' +
' </form>\n' +
'</div>',
id: 'page1', //定义 ID,防止重复弹出
success:function () {
uploadInst=upload.render({
elem: '#har_file',
url:'/import_har/', //上传接口
accept: 'file',
acceptMime: 'file|har',
exts: 'har',
auto: false, //自动上传关闭
multiple: false,//关闭多文件上传
drag: false,//禁止拖拽上传
bindAction: '#commit',
before: function(){ //文件提交上传前的回调
this.data = { //传给后台的参数
input_name: $('input[name="input_name"]').val()
};
if (this.data.input_name===''){
return false;
}else {
layer.load(2);
}
},
done: function(res){ //上传完毕回调
if(res.code === 0){
layer.closeAll('loading');
layer.close(index);
layer.msg(res.msg);
}else {
layer.closeAll('loading');
layer.close(index);
layer.alert(res.msg,{icon: 5,title: '提示'});
}
},
error: function(){ //请求异常回调
layer.closeAll('loading');
layer.msg('提交错误',{icon: 5,title: '提示'});
}
})
},
});
})
})
这里弹出层的div必须将代码写在content里,不能使用选择器,否则会有个Bug:第二次打开弹窗的时候,选择上传文件后不会显示文件的名称。
before回调里面需要判断一下输入框是否为空,为空的话 return false阻止上传,否则会有个bug:当输入框为空、但是有选择文件的时候,点击【提交】,还是会去请求接口
upload.render参数说明
参数 | 说明 |
---|---|
elem | 指向容器选择器,如:elem: '#id'。也可以是DOM对象 |
url | 请求的接口 |
data | 传给接口的额外参数,如:data: |
headers | 接口的请求头。如:headers: |
accept | 指定允许上传时校验的文件类型,可选值有:images(图片)、file(所有文件)、video(视频)、audio(音频) |
acceptMime | 规定打开文件选择框时,筛选出的文件类型,值为用逗号隔开的 MIME 类型列表。如:acceptMime: 'image/*'(只显示图片文件) acceptMime: 'image/jpg, image/png'(只显示 jpg 和 png 文件) |
exts | 允许上传的文件后缀。一般结合 accept 参数类设定。 |
auto | 是否选完文件后自动上传。如果设定 false,那么需要设置 bindAction 参数来指向一个按钮提交上传 |
bindAction | 指向一个按钮触发上传,一般配合 auto: false 来使用。值为选择器或DOM对象 |
field | 设定文件域的字段名 |
size | 设置文件最大可允许上传的大小,单位 KB。不支持ie8/9 |
multiple | 是否允许多文件上传。设置 true即可开启。不支持ie8/9 |
number | 设置同时可上传的文件数量,一般配合 multiple 参数出现。 |
drag | 是否接受拖拽的文件上传,设置 false 可禁用。不支持ie8/9 |
field | 设定文件域的字段名 |
回调参数 | 说明 |
---|---|
choose | 选择文件后的回调函数。返回一个object参数 |
before | 文件提交上传前的回调。返回一个object参数 |
done | 执行上传请求后的回调。返回三个参数,分别为:res(服务端响应信息)、index(当前文件的索引)、upload(重新上传的方法,一般在文件上传失败后使用)。 |
error | 执行上传请求出现异常的回调(一般为网络异常、URL 404等)。返回两个参数,分别为:index(当前文件的索引)、upload(重新上传的方法)。 |
接口返回的响应信息(response)必须是一个标准的 JSON 格式
接口处理:
basedir = os.path.abspath(os.path.dirname(__file__)) # 项目路径
UPLOAD_PATH = os.path.join(basedir, 'upload') #上传/下载路径
ALLOWED_EXTENSIONS = ['har'] #允许上传文件类型
# 判断文件类型
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# 上传har文件
@app.route('/import_har/',methods=['post'])
def import_har():
input_name = request.values.get('input_name')
file = request.files['file']
print('input_name:',input_name,'file:',file)
if file and allowed_file(file.filename):
file_dir = os.path.join(UPLOAD_PATH,file.filename) # 要增加的文件
add_obj = File(file_name=file.filename, input_name=input_name) # 数据库要增加的内容
if not os.path.exists(file_dir): # 如果该文件不存在
try:
file.save(file_dir)
db.session.add(add_obj)
db.session.commit()
return jsonify({'code': 0,'msg': '上传成功'})
except Exception as e:
return jsonify({'code': e, 'msg': '操作失败,请重试'})
else:
return jsonify({'code': 1, 'msg': '文件已存在','file':file_dir})
else:
return jsonify({'code': 2, 'msg': '上传格式错误'})
我是将文件名称存数据库,将文件保存在本地的。
表结构:
class File(db.Model):
__tablename__ = 'file' # 表名
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 主键
file_name = db.Column(db.String(200), nullable=False) # 分类名称、不能为空
input_name = db.Column(db.String(200), nullable=False) # 不能为空