flask 项目中使用 bootstrapFileInput(进阶篇)

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 示例为基础进行讲解.

创建蓝图 advanced

创建方法请参照 flask 项目中使用 bootstrapFileInput(构建篇) 中 lib 蓝图的创建方法,此处不在赘述.

构建基础 html 模板

app/advanced/templates/advanced_common/base.html 内容如下:

<!DOCTYPE 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">
        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
        <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 %}
            <!-- 新 Bootstrap 核心 CSS 文件 -->
            <link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap.min.css') }}">

            <!-- 可选的Bootstrap主题文件(一般不用引入) -->
            <link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap-theme.min.css') }}">

            <!-- 个性化主题文件 -->
            <!-- font-awesome样式主题文体 -->
            <link href="{{ url_for('lib.static',filename='css/font-awesome.css') }}" media="all" rel="stylesheet" type="text/css" />
            <!-- fileinput样式主题文体 -->
            <link href="{{ url_for('lib.static',filename='css/fileinput.min.css') }}" media="all" rel="stylesheet" type="text/css" />
        {% endblock %}

        {% block js %}
            <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
            <script src="{{ url_for('lib.static', filename='js/jquery.min.js') }}"></script>

            <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
            <script src="{{ url_for('lib.static', filename='js/bootstrap.min.js') }}"></script>

            <!-- 个性化 js 文件 -->
            <!-- piexif.min.js is only needed if you wish to resize images before upload to restore exif data.
             This must be loaded before fileinput.min.js -->
            <script src="{{ url_for('lib.static',filename='js/plugins/piexif.min.js') }}" type="text/javascript"></script>
            <!-- sortable.min.js is only needed if you wish to sort / rearrange files in initial preview.
                 This must be loaded before fileinput.min.js -->
            <script src="{{ url_for('lib.static',filename='js/plugins/sortable.min.js') }}" type="text/javascript"></script>
            <!-- purify.min.js is only needed if you wish to purify HTML content in your preview for HTML files.
                 This must be loaded before fileinput.min.js -->
            <script src="{{ url_for('lib.static',filename='js/plugins/purify.js') }}" type="text/javascript"></script>
            <!-- the main fileinput plugin file -->
            <script src="{{ url_for('lib.static',filename='js/fileinput.min.js') }}"></script>
            <!-- optionally if you need a theme like font awesome theme you can include
                it as mentioned below -->
            <script src="{{ url_for('lib.static',filename='js/themes/fa/theme.min.js') }}"></script>
            <!-- optionally if you need translation for your language then include
                locale file as mentioned below -->
            <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><!--/row-->
        </div><!--/.container-->
    </body>
</html>

base.html 模板引入 css 和 js 时的几个坑

注意 css 和 js 文件的导入顺序

  • 首先需要导入的 js 文件是 jquery.js.
  • 第二需要导入 bootstrap 相关的 css 和 js.
  • 第三需要导入 fileinput 相关的 css 和 js, 请注意项目中的注释, 相关的文件导入也需要有先后顺序的要求.

注意版本问题

  • 此项目所需的 jquery 是 jQuery v2.1.1.
  • 此项目所需的 bootstrap 是 v3.3.7 版本
  • 此项目所需的 fileinput 是 v4.4.2 的版本.

其它版本可能会有所不同.

注意 fileinput 使用模式

fileinput 有两种使用模式,一种是利用 form 提交,一种是 ajax 方式提交.其中 ajax 提交方式,需要从 js 中进行设置, 并将类样式 class 设置为 file-loading. 而非 ajax 提交方式需要引入 form 表单, 类样式 class 需设置为 file, 本基础示例都需要引入 form 表单.

进阶示例 1

展示

image

从该图的右下角可以清晰的看到, 这个 form data 里裹夹着数据 key: 2. 那么我们用 flask 写视图函数的时候,就可以用到这个 key 值.

模板内容

app/advanced/templates/exam_1.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例1</h1>
<label class="control-label">Planets and Satellites</label>
<input id="input-24" name="input24[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-24").fileinput({
        initialPreview: [
            'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/631px-FullMoon2010.jpg',
            'http://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Earth_Eastern_Hemisphere.jpg/600px-Earth_Eastern_Hemisphere.jpg'
        ],
        initialPreviewAsData: true,
        initialPreviewConfig: [
            {caption: "Moon.jpg", size: 6930321, width: "120px", key: 1},
            {caption: "Earth.jpg", size: 1218822, width: "120px", key: 2}
        ],
        deleteUrl: "{{ url_for('advanced.delete') }}",
        overwriteInitial: false,
        maxFileSize: 100,
        initialCaption: "进阶示例第一例"
    });
});
</script>
<hr>
<p>
    设置最大的文件上传大小为 100K . 展示服务器上的图片内容,实现 finder 功能. 设置 <code>overwriteInitial</code> 为 <code>false</code>, 新选择的文件不会覆盖原有文件.
</p>
{% endblock %}
{% block title %}
    进阶示例1
{% endblock %}

知识点

  1. html 模板的名称最好在整个项目中,也就是所有的蓝图中都具有唯一性.
  2. 模板中的 js 代码有多种写法, 详细内容请见: http://plugins.krajee.com/file-input#options
  3. 请注意 js 代码中的 deleteUrl 项, 此处有多种写法. 请参阅第二点之后, 选择适合自己的方法.
  4. 请大胆的想象, 如果此示例实际上已具有 finder 的影子.你可以实现文件上传, 删除, 更新, 展示等所有你能想象的功能.
  5. initialPreviewAsData 项, 如果设置为 false, 将不会展示图片,而只会显示图片链接, 如果设置为 true, 则展示图片.
  6. overwriteInitial 项, 是设置是否覆盖原有的已上传项.
  7. maxFileSize 项, 上传文件的最大大小.
  8. initialCaption 项, 初始化 input 选择框内的内容.

视图函数

app/advanced/views.py 内容如下:

@advanced.route('/delete', methods=['GET', 'POST'])
def delete():
    key = request.form.get('key')
    print key

    return jsonify()


@advanced.route('/example_1', methods=['GET', 'POST'])
def example_1():

    return render_template('exam_1.html')

知识点

  1. 第一个 url 函数是实现了文件的删除功能. 其中的 request.form.get('key') 就是为了获取 ajax 提交的 form data 的值, 也就是示意图中右下角所展示的内容.
  2. 第二个 url 函数实现了上传功能的页面.

进阶示例 2

该示例仅仅是把 js 中的 overwriteInitial 项设置成了 true, 选择新文件的时候, 将会覆盖原有的文件.

进阶示例 3

模板内容

app/advanced/templates/exam_3.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例3</h1>
<label class="control-label">Select File</label>
<input id="input-20" type="file" class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-20").fileinput({
        browseClass: "btn btn-primary btn-block",
        showCaption: false,
        showRemove: false,
        showUpload: false
    });
});
</script>
{% endblock %}
{% block title %}
    进阶示例3
{% endblock %}

知识点

  1. browseClass 项, 用来设置上传按钮的样式.
  2. showCaption 项, 用来设置是否显示文件选择 input 框.
  3. showRemove 项, 用来设置是否显示删除按钮.
  4. showUpload 项, 用来设置是否显示上传按钮.
  5. 该示例仅仅显示选择文件按钮, 仅此而已.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 4

模板内容

app/advanced/templates/exam_4.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例4</h1>
<label class="control-label">Select File</label>
<input id="input-21" type="file" accept="image/*" class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-21").fileinput({
        previewFileType: "image",
        browseClass: "btn btn-success",
        browseLabel: "Pick Image",
        browseIcon: "<i class=\"glyphicon glyphicon-picture\"></i> ",
        removeClass: "btn btn-danger",
        removeLabel: "Delete",
        removeIcon: "<i class=\"glyphicon glyphicon-trash\"></i> ",
        uploadClass: "btn btn-info",
        uploadLabel: "Upload",
        uploadIcon: "<i class=\"glyphicon glyphicon-upload\"></i> "
    });
});
</script>
{% endblock %}
{% block title %}
    进阶示例4
{% endblock %}

知识点

  1. accept="image/*", input 标签中的属性, 表示只能选择图片文件.
  2. previewFileType: image 设置要选择的文件格式是图片格式.
  3. 其它的都是为了设置各个按钮的样式, 可以自由组合.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 5

模板内容

app/advanced/templates/exam_5.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例5</h1>
<label class="control-label">Select File</label>
<input id="input-22" name="input22[]" type="file" class="file-loading" accept="text/plain" multiple>
<script>
$(document).on('ready', function() {
    $("#input-22").fileinput({
        previewFileType: "text",
        allowedFileExtensions: ["txt", "md", "ini", "text"],
        previewClass: "bg-warning"
    });
});
</script>
{% endblock %}
{% block title %}
    进阶示例5
{% endblock %}

知识点

  1. previewFileType: "text" 设置要选择的文件格式是文件格式.
  2. allowedFileExtensions 设置能够接受上传的集中文件的格式, 具有验证功能.
  3. previewClass 预览框的背景样式.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 6

模板内容

app/advanced/templates/exam_6.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例6</h1>
<label class="control-label">Select File</label>
<input id="input-23" name="input23[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-23").fileinput({
        showUpload: false,
        layoutTemplates: {
            main1: "{preview}\n" +
            "<div class=\'input-group {class}\'>\n" +
            "   <div class=\'input-group-btn\'>\n" +
            "       {browse}\n" +
            "       {upload}\n" +
            "       {remove}\n" +
            "   </div>\n" +
            "   {caption}\n" +
            "</div>"
        }
    });
});
</script>
{% endblock %}
{% block title %}
    进阶示例6
{% endblock %}

知识点

  1. showUpload: false. 不显示上传按钮.
  2. layoutTemplates. 用于设置文件上传插件的样式. 详见 http://plugins.krajee.com/file-input#options 的 layoutTemplates 项.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 7

模板内容

app/advanced/templates/exam_7.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例7</h1>
<label class="control-label">Select File</label>
<input id="input-40" name="input40[]" type="file" class="file" multiple>
<br>
<button type="button" class="btn btn-warning btn-modify">Modify</button>
<script>
$(document).on('ready', function() {
    $(".btn-modify").on("click", function() {
        var $btn = $(this), $input = $("#input-40");
        if ($btn.text() == "Modify") {
            $("#input-40").fileinput("disable").fileinput("refresh", {showUpload: false});
            $btn.html("Revert");
            alert("Hurray! I have disabled the input and hidden the upload button.");
        }
        else {
            $("#input-40").fileinput("enable").fileinput("refresh", {showUpload: true});
            $btn.html("Modify");
            alert("Hurray! I have reverted back the input to enabled with the upload button.");
        }
    });
});
</script>
<br>
<p>
    调用插件方法, 点击 modify 按钮来打开获关闭插件功能.
</p>
{% endblock %}
{% block title %}
    进阶示例7
{% endblock %}

知识点

  1. $("#input-40").fileinput("disable").fileinput("refresh", {showUpload: false}); 其中,第一个 fileinput("disable") 的功能是让文件上传插件不可用. 第二个 fileinput("refresh", {showUpload: false}) 的功能是不显示上传预览模板.
  2. 如果只调用第一个 fileinput("disable"), 将只是关闭文件上传插件, 假如你已经选择了文件, 已有预览效果图, 则不关闭预览效果图.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 8

模板内容

app/advanced/templates/exam_8.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例8</h1>
<label class="control-label">Select File</label>
<input id="input-41" name="input41[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-41").fileinput({
        maxFileCount: 10,
        allowedFileTypes: ["image", "video"]
    });
});
</script>
<br>
<p>
    仅仅允许上传的文件为图片和视频. 最大上传的文件数是 10.
</p>
{% endblock %}
{% block title %}
    进阶示例8
{% endblock %}

知识点

  1. allowedFileTypes: ["image", "video"] 插件的验证功能, 仅仅允许上传的文件为图片和视频. 可以将 "image", "video" 换成 "text" 试试.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 9

模板内容

app/advanced/templates/exam_9.html 内容如下:

<label class="control-label">Select File</label>
<input id="input-42" name="input42[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-42").fileinput({
        maxFileCount: 10,
        allowedFileExtensions: ["jpg", "gif", "png", "txt"]
    });
});
</script>

知识点

  1. allowedFileExtensions 插件的验证功能, 仅仅允许上传后缀为 "jpg", "gif", "png", "txt" 的文件.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 10

模板内容

app/advanced/templates/exam_10.html 内容如下:

{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>进阶示例10</h1>
<label class="control-label">Select File</label>
<input id="input-43" name="input43[]" type="file" multiple class="file-loading">
<div id="errorBlock" class="help-block"></div>
<script>
$(document).on('ready', function() {
    $("#input-43").fileinput({
        showPreview: false,
        allowedFileExtensions: ["jpg", "jpeg", "gif", "png"],
        elErrorContainer: "#errorBlock"
    });
});
</script>
<br>
<p>
    仅仅允许上传后缀为 "jpg", "gif", "png", "txt" 的文件. 不显示文件预览功能. 且设置错误提示的显示位置.
</p>
{% endblock %}
{% block title %}
    进阶示例10
{% endblock %}

知识点

  1. showPreview: false, 不显示文件的预览功能.
  2. elErrorContainer: "#errorBlock". 设置 id 为 errorBlock 的区域来显示错误提示.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

进阶示例 11

模板内容

app/advanced/templates/exam_11.html 内容如下:

<label class="control-label">Select File</label>
<input id="input-44" name="input44[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
    $("#input-44").fileinput({
        uploadUrl: '/file-upload-batch/2',
        maxFilePreviewSize: 10240
    });
});
</script>

知识点

  1. uploadUrl 设置上传文件的链接. 此处请参阅 flask 项目中使用 bootstrapFileInput(基础篇) 中的视图函数内容.
  2. maxFilePreviewSize: 10240 验证功能, 设置预览的文件的大小最大为 10M.

视图函数

views.py 视图函数和示例1基本相同,不在赘述.

本章源代码下载:

<a class="btn btn-primary" href="https://github.com/eastossifrage/bootstrapFileInput/archive/v1.3.zip">zip压缩包</a>
<a class="btn btn-primary" href="https://github.com/eastossifrage/bootstrapFileInput/archive/v1.3.tar.gz">tar.gz压缩包</a>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • bootstrap 为 flask 使用人员提供了一个非常优美且有效的前端页面组件,但是完美之处还存在些许缺陷,比...
    藕丝空间阅读 1,793评论 0 1
  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,174评论 22 257
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,068评论 4 62
  • 莲子可以沉睡万年不死, 一旦发芽便失去了永恒。 作为生的对立, 死只是一个开始。 一 那场相遇来得突然,我来不及整...
    美娜宝阅读 240评论 0 0
  • 【久未提笔,略生疏……记今日雨,娱众一乐】 无题 ——忭迴 薄暮细雨月朦胧, ...
    咘倒翁阅读 236评论 0 2