bootstrap 为 flask 使用人员提供了一个非常优美且有效的前端页面组件,但是完美之处还存在些许缺陷,比如文件的上传功能.而 bootstrap-fileinput 是基于 bootstrap 的控件,非常完美的填补了这个空缺.
注意:
本文是基于 bootstrap-fileinput v4.4.2. github 地址: https://github.com/kartik-v/bootstrap-fileinput
注意:
本文是主要是以 http://plugins.krajee.com/file-input/demo 示例为基础进行讲解.
创建方法请参照 flask 项目中使用 bootstrapFileInput(构建篇) 中 lib 蓝图的创建方法,此处不在赘述.
app/basic/templates/basic_common/base.html
内容如下:
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{{ url_for('lib.static', filename='favicon.ico')}}">
<title>{% block title %}{% endblock %}title>
{% block css %}
<link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap-theme.min.css') }}">
<link href="{{ url_for('lib.static',filename='css/font-awesome.css') }}" media="all" rel="stylesheet" type="text/css" />
<link href="{{ url_for('lib.static',filename='css/fileinput.min.css') }}" media="all" rel="stylesheet" type="text/css" />
{% endblock %}
{% block js %}
<script src="{{ url_for('lib.static', filename='js/jquery.min.js') }}">script>
<script src="{{ url_for('lib.static', filename='js/bootstrap.min.js') }}">script>
<script src="{{ url_for('lib.static',filename='js/plugins/piexif.min.js') }}" type="text/javascript">script>
<script src="{{ url_for('lib.static',filename='js/plugins/sortable.min.js') }}" type="text/javascript">script>
<script src="{{ url_for('lib.static',filename='js/plugins/purify.js') }}" type="text/javascript">script>
<script src="{{ url_for('lib.static',filename='js/fileinput.min.js') }}">script>
<script src="{{ url_for('lib.static',filename='js/themes/fa/theme.min.js') }}">script>
<script src="{{ url_for('lib.static',filename='js/locales/zh.js') }}">script>
{% endblock %}
head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-offset-2">
<div class="col-xs-12 col-sm-8">
{% block content %}
{% endblock %}
div>
div>
div>
div>
body>
html>
其它版本可能会有所不同.
fileinput 有两种使用模式,一种是利用 form 提交,一种是 ajax 方式提交.其中 ajax 提交方式,需要从 js 中进行设置, 并将类样式 class 设置为 file-loading
. 而非 ajax 提交方式需要引入 form 表单, 类样式 class 需设置为 file
, 本基础示例都需要引入 form 表单.
app/basic/templates/example_1.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例1 -- 自动展示缩略图h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-1" name="input-1" type="file" class="file">
form>
{% endblock %}
{% block title %}
基本示例1 -- 自动展示缩略图
{% endblock %}
enctype="multipart/form-data"
.app/basic/views.py
内容如下:
# -*- coding:utf-8 -*-
__author__ = '东方鹗'
from flask import render_template, request, current_app, redirect, url_for
from . import basic
from werkzeug.utils import secure_filename
import os
def allowed_file(filename):
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@basic.route('/example_1', methods=['GET', 'POST'])
def example_1():
if request.method == 'POST':
file = request.files['input-1']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
return render_template('example_1.html')
app/basic/templates/example_2.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例2 -- 隐藏展示缩略图h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-2" name="input-2" type="file" class="file" data-show-preview="false">
form>
{% endblock %}
{% block title %}
基本示例2 -- 隐藏展示缩略图
{% endblock %}
$(document).on('ready', function() {
$("#input-2").fileinput({
show-preview: false
});
});
views.py 视图函数和示例1基本相同,不在赘述.
app/basic/templates/example_3.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例3 -- 利用 file input 属性控制相关选项,如本例可实现多文件上传,但不显示上传按钮h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-3" name="input3[]" type="file" class="file" multiple data-show-upload="false" data-show-caption="true">
form>
{% endblock %}
{% block title %}
基本示例3 -- 利用 file input 属性控制相关选项,如本例可实现多文件上传,但不显示上传按钮
{% endblock %}
$(document).on('ready', function() {
$("#input-3").fileinput({
show-upload: false,
show-caption: true
});
});
由于没有上传按钮, 故无需处理选择的文件. 视图函数无需改变.
app/basic/templates/example_4.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例4 -- 设置属性为只读或不可用h1>
<label class="control-label">Select Filelabel>
<label class="control-label">Readonly Inputlabel>
<input id="input-4a" type="file" class="file" readonly="true">
<label class="control-label">Disabled Inputlabel>
<input id="input-4b" type="file" class="file" disabled="true">
{% endblock %}
{% block title %}
基本示例4 -- 设置属性为只读或不可用
{% endblock %}
由于无法选择文件, 视图函数无需改变.
app/basic/templates/example_5.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例5 -- 设置为单按钮并隐藏文件选择输入框,在上传时显示上传等待图标h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-5" name="input-5[]" type="file" multiple class="file-loading">
form>
<script>
$(document).on('ready', function() {
$("#input-5").fileinput({showCaption: false});
});
script>
{% endblock %}
{% block title %}
基本示例5 -- 设置为单按钮并隐藏文件选择输入框,在上传时显示上传等待图标
{% endblock %}
app/basic/views.py
内容如下:
...
@basic.route('/example_5', methods=['GET', 'POST'])
def example_5():
if request.method == 'POST':
files = request.files.getlist('input-5[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
return render_template('example_5.html')
...
app/basic/templates/example_6.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例6 -- 设置最大上传的文件数为10h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-6" name="input6[]" type="file" multiple class="file-loading">
form>
<script>
$(document).on('ready', function() {
$("#input-6").fileinput({
showUpload: false,
maxFileCount: 10,
mainClass: "input-group-lg"
});
});
script>
{% endblock %}
{% block title %}
基本示例6 -- 设置最大上传的文件数为10
{% endblock %}
由于没有上传按钮, 故无需处理选择的文件. 视图函数无需改变.
app/basic/templates/example_7.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例7 -- 设置允许上传的文件格式h1>
<label class="control-label">Select Filelabel>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-7" name="input-7[]" multiple type="file" class="file file-loading" data-allowed-file-extensions='["csv", "txt"]'>
form>
{% endblock %}
{% block title %}
基本示例7 -- 设置允许上传的文件格式
{% endblock %}
app/basic/views.py
内容如下:
...
@basic.route('/example_7', methods=['GET', 'POST'])
def example_7():
if request.method == 'POST':
files = request.files.getlist('input-7[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
return render_template('example_7.html')
...
app/basic/templates/example_8.html
内容如下:
{% extends 'basic_common/base.html' %}
{% block content %}
<h1>基本示例8 -- 使用rtl样式,让文件选择按钮居左h1>
<span>注意:引入样式文件的时候, css/fileinput-rtl.css 必须在 the css/fileinput.css 之后引入span>
<div dir=rtl>
<label class="control-label">Select Filelabel>
div>
<form method="post" role="form" enctype="multipart/form-data">
<input id="input-8" name="input-8[]" multiple type="file" class="file-loading">
form>
<script>
$(document).on('ready', function() {
$("#input-8").fileinput({
rtl: true,
allowedFileExtensions: ["jpg", "png", "gif"]
});
});
script>
{% endblock %}
{% block title %}
基本示例8 -- 使用rtl样式,让文件选择按钮居左
{% endblock %}
{% block css %}
{{ super() }}
<link href="{{ url_for('lib.static',filename='css/fileinput-rtl.min.css') }}" media="all" rel="stylesheet" type="text/css" />
{% endblock %}
css/fileinput-rtl.min.css
样式表, 注意 flask 模板的导入方式. 此属性将是按钮的样式反转.app/basic/views.py
内容如下:
...
@basic.route('/example_8', methods=['GET', 'POST'])
def example_8():
if request.method == 'POST':
files = request.files.getlist('input-8[]')
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
return render_template('example_8.html')
...
本章源代码下载:
zip压缩包
tar.gz压缩包