flask 項目中使用 bootstrapFileInput(進階篇)

bootstrap 為 flask 使用人員提供了一個非常優(yōu)美且有效的前端頁面組件,但是完美之處還存在些許缺陷,比如文件的上傳功能.而 bootstrap-fileinput 是基于 bootstrap 的控件,非常完美的填補了這個空缺.

注意: 本文是基于 bootstrap-fileinput v4.4.2. github 地址: https://github.com/kartik-v/bootstrap-fileinput

注意: 本文是主要是以 http://plugins.krajee.com/file-input/demo 示例為基礎(chǔ)進行講解.

創(chuàng)建藍圖 advanced

創(chuàng)建方法請參照 flask 項目中使用 bootstrapFileInput(構(gòu)建篇) 中 lib 藍圖的創(chuàng)建方法,此處不在贅述.

構(gòu)建基礎(chǔ) html 模板

app/advanced/templates/advanced_common/base.html 內(nèi)容如下:

<!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文件。務(wù)必在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 文件的導(dǎo)入順序

  • 首先需要導(dǎo)入的 js 文件是 jquery.js.
  • 第二需要導(dǎo)入 bootstrap 相關(guān)的 css 和 js.
  • 第三需要導(dǎo)入 fileinput 相關(guān)的 css 和 js, 請注意項目中的注釋, 相關(guān)的文件導(dǎo)入也需要有先后順序的要求.

注意版本問題

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

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

注意 fileinput 使用模式

fileinput 有兩種使用模式,一種是利用 form 提交,一種是 ajax 方式提交.其中 ajax 提交方式,需要從 js 中進行設(shè)置, 并將類樣式 class 設(shè)置為 file-loading. 而非 ajax 提交方式需要引入 form 表單, 類樣式 class 需設(shè)置為 file, 本基礎(chǔ)示例都需要引入 form 表單.

進階示例 1

展示

image

從該圖的右下角可以清晰的看到, 這個 form data 里裹夾著數(shù)據(jù) key: 2. 那么我們用 flask 寫視圖函數(shù)的時候,就可以用到這個 key 值.

模板內(nèi)容

app/advanced/templates/exam_1.html 內(nèi)容如下:

{% 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>
    設(shè)置最大的文件上傳大小為 100K . 展示服務(wù)器上的圖片內(nèi)容,實現(xiàn) finder 功能. 設(shè)置 <code>overwriteInitial</code> 為 <code>false</code>, 新選擇的文件不會覆蓋原有文件.
</p>
{% endblock %}
{% block title %}
    進階示例1
{% endblock %}

知識點

  1. html 模板的名稱最好在整個項目中,也就是所有的藍圖中都具有唯一性.
  2. 模板中的 js 代碼有多種寫法, 詳細內(nèi)容請見: http://plugins.krajee.com/file-input#options
  3. 請注意 js 代碼中的 deleteUrl 項, 此處有多種寫法. 請參閱第二點之后, 選擇適合自己的方法.
  4. 請大膽的想象, 如果此示例實際上已具有 finder 的影子.你可以實現(xiàn)文件上傳, 刪除, 更新, 展示等所有你能想象的功能.
  5. initialPreviewAsData 項, 如果設(shè)置為 false, 將不會展示圖片,而只會顯示圖片鏈接, 如果設(shè)置為 true, 則展示圖片.
  6. overwriteInitial 項, 是設(shè)置是否覆蓋原有的已上傳項.
  7. maxFileSize 項, 上傳文件的最大大小.
  8. initialCaption 項, 初始化 input 選擇框內(nèi)的內(nèi)容.

視圖函數(shù)

app/advanced/views.py 內(nèi)容如下:

@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 函數(shù)是實現(xiàn)了文件的刪除功能. 其中的 request.form.get('key') 就是為了獲取 ajax 提交的 form data 的值, 也就是示意圖中右下角所展示的內(nèi)容.
  2. 第二個 url 函數(shù)實現(xiàn)了上傳功能的頁面.

進階示例 2

該示例僅僅是把 js 中的 overwriteInitial 項設(shè)置成了 true, 選擇新文件的時候, 將會覆蓋原有的文件.

進階示例 3

模板內(nèi)容

app/advanced/templates/exam_3.html 內(nèi)容如下:

{% 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 項, 用來設(shè)置上傳按鈕的樣式.
  2. showCaption 項, 用來設(shè)置是否顯示文件選擇 input 框.
  3. showRemove 項, 用來設(shè)置是否顯示刪除按鈕.
  4. showUpload 項, 用來設(shè)置是否顯示上傳按鈕.
  5. 該示例僅僅顯示選擇文件按鈕, 僅此而已.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 4

模板內(nèi)容

app/advanced/templates/exam_4.html 內(nèi)容如下:

{% 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 設(shè)置要選擇的文件格式是圖片格式.
  3. 其它的都是為了設(shè)置各個按鈕的樣式, 可以自由組合.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 5

模板內(nèi)容

app/advanced/templates/exam_5.html 內(nèi)容如下:

{% 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" 設(shè)置要選擇的文件格式是文件格式.
  2. allowedFileExtensions 設(shè)置能夠接受上傳的集中文件的格式, 具有驗證功能.
  3. previewClass 預(yù)覽框的背景樣式.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 6

模板內(nèi)容

app/advanced/templates/exam_6.html 內(nèi)容如下:

{% 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. 用于設(shè)置文件上傳插件的樣式. 詳見 http://plugins.krajee.com/file-input#options 的 layoutTemplates 項.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 7

模板內(nèi)容

app/advanced/templates/exam_7.html 內(nèi)容如下:

{% 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>
    調(diào)用插件方法, 點擊 modify 按鈕來打開獲關(guān)閉插件功能.
</p>
{% endblock %}
{% block title %}
    進階示例7
{% endblock %}

知識點

  1. $("#input-40").fileinput("disable").fileinput("refresh", {showUpload: false}); 其中,第一個 fileinput("disable") 的功能是讓文件上傳插件不可用. 第二個 fileinput("refresh", {showUpload: false}) 的功能是不顯示上傳預(yù)覽模板.
  2. 如果只調(diào)用第一個 fileinput("disable"), 將只是關(guān)閉文件上傳插件, 假如你已經(jīng)選擇了文件, 已有預(yù)覽效果圖, 則不關(guān)閉預(yù)覽效果圖.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 8

模板內(nèi)容

app/advanced/templates/exam_8.html 內(nèi)容如下:

{% 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>
    僅僅允許上傳的文件為圖片和視頻. 最大上傳的文件數(shù)是 10.
</p>
{% endblock %}
{% block title %}
    進階示例8
{% endblock %}

知識點

  1. allowedFileTypes: ["image", "video"] 插件的驗證功能, 僅僅允許上傳的文件為圖片和視頻. 可以將 "image", "video" 換成 "text" 試試.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 9

模板內(nèi)容

app/advanced/templates/exam_9.html 內(nèi)容如下:

<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" 的文件.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 10

模板內(nèi)容

app/advanced/templates/exam_10.html 內(nèi)容如下:

{% 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" 的文件. 不顯示文件預(yù)覽功能. 且設(shè)置錯誤提示的顯示位置.
</p>
{% endblock %}
{% block title %}
    進階示例10
{% endblock %}

知識點

  1. showPreview: false, 不顯示文件的預(yù)覽功能.
  2. elErrorContainer: "#errorBlock". 設(shè)置 id 為 errorBlock 的區(qū)域來顯示錯誤提示.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

進階示例 11

模板內(nèi)容

app/advanced/templates/exam_11.html 內(nèi)容如下:

<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 設(shè)置上傳文件的鏈接. 此處請參閱 flask 項目中使用 bootstrapFileInput(基礎(chǔ)篇) 中的視圖函數(shù)內(nèi)容.
  2. maxFilePreviewSize: 10240 驗證功能, 設(shè)置預(yù)覽的文件的大小最大為 10M.

視圖函數(shù)

views.py 視圖函數(shù)和示例1基本相同,不在贅述.

本章源代碼下載:

<a class="btn btn-primary" >zip壓縮包</a>
<a class="btn btn-primary" >tar.gz壓縮包</a>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • bootstrap 為 flask 使用人員提供了一個非常優(yōu)美且有效的前端頁面組件,但是完美之處還存在些許缺陷,比...
    藕絲空間閱讀 1,826評論 0 1
  • 22年12月更新:個人網(wǎng)站關(guān)停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,224評論 22 257
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,232評論 4 61
  • 蓮子可以沉睡萬年不死, 一旦發(fā)芽便失去了永恒。 作為生的對立, 死只是一個開始。 一 那場相遇來得突然,我來不及整...
    美娜寶閱讀 252評論 0 0
  • 【久未提筆,略生疏……記今日雨,娛眾一樂】 無題 ——忭迴 薄暮細雨月朦朧, ...
    咘倒翁閱讀 246評論 0 2