效果图
代码说明 bootstrap-table
操作指南
修改虚拟环境中的 模板 base.html
cd venv/lib/python2.7/site-packages/flask_admin/templates/bootstrap3/adminvim base.html
内容如下:{% import 'admin/layout.html' as layout with context -%} {% import 'admin/static.html' as admin_static with context %} <!DOCTYPE html > <html > <head > <title > {% block title %}{% if admin_view.category %}{{ admin_view.category }} - {% endif %}{{ admin_view.name }} - {{ admin_view.admin.name }}{% endblock %}</title > {% block head_meta %} <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge,chrome=1" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <meta name ="description" content ="" > <meta name ="author" content ="" > {% endblock %} {% block head_css %} <link href ="{{ admin_static.url(filename='bootstrap/bootstrap3/swatch/{swatch}/bootstrap.min.css'.format(swatch=config.get('FLASK_ADMIN_SWATCH', 'default')), v='3.3.5') }}" rel ="stylesheet" > {%if config.get('FLASK_ADMIN_SWATCH', 'default') == 'default' %} <link href ="{{ admin_static.url(filename='bootstrap/bootstrap3/css/bootstrap-theme.min.css', v='3.3.5') }}" rel ="stylesheet" > {%endif%} <link href ="{{ admin_static.url(filename='admin/css/bootstrap3/admin.css', v='1.1.1') }}" rel ="stylesheet" > <link href ="{{ admin_static.url(filename='admin/css/bootstrap3/submenu.css') }}" rel ="stylesheet" > {% if admin_view.extra_css %} {% for css_url in admin_view.extra_css %} <link href ="{{ css_url }}" rel ="stylesheet" > {% endfor %} {% endif %} <style > body { padding-top : 4px ; } </style > <link rel ="stylesheet" href ="https://unpkg.com/@fortawesome/fontawesome-free@5.12.1/css/all.min.css" > <script src ="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity ="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin ="anonymous" > </script > <link href ="https://unpkg.com/bootstrap-table@1.18.0/dist/bootstrap-table.min.css" rel ="stylesheet" > <script src ="https://unpkg.com/bootstrap-table@1.18.0/dist/bootstrap-table.min.js" > </script > <script id ="_carbonads_projs" type ="text/javascript" src ="https://srv.carbonads.net/ads/CK7DL2J7.json?segment=placement:bootstrap-tablecom& callback=_carbonads_go" > </script > {% endblock %} {% block head %} {% endblock %} {% block head_tail %} {% endblock %} </head > <body > {% block page_body %} <div class ="container{%if config.get('FLASK_ADMIN_FLUID_LAYOUT', False) %}-fluid{% endif %}" > <nav class ="navbar navbar-default" role ="navigation" > <div class ="navbar-header" > <button type ="button" class ="navbar-toggle" data-toggle ="collapse" data-target ="#admin-navbar-collapse" > <span class ="sr-only" > Toggle navigation</span > <span class ="icon-bar" > </span > <span class ="icon-bar" > </span > <span class ="icon-bar" > </span > </button > {% block brand %} <a class ="navbar-brand" href ="{{ admin_view.admin.url }}" > {{ admin_view.admin.name }}</a > {% endblock %} </div > <div class ="collapse navbar-collapse" id ="admin-navbar-collapse" > {% block main_menu %} <ul class ="nav navbar-nav" > {{ layout.menu() }} </ul > {% endblock %} {% block menu_links %} <ul class ="nav navbar-nav navbar-right" > {{ layout.menu_links() }} </ul > {% endblock %} {% block access_control %} {% endblock %} </div > </nav > {% block messages %} {{ layout.messages() }} {% endblock %} {# store the jinja2 context for form_rules rendering logic #} {% set render_ctx = h.resolve_ctx() %} {% block body %}{% endblock %} </div > {% endblock %} {% block tail_js %} <script src ="{{ admin_static.url(filename='vendor/jquery.min.js', v='2.1.4') }}" type ="text/javascript" > </script > <script src ="{{ admin_static.url(filename='bootstrap/bootstrap3/js/bootstrap.min.js', v='3.3.5') }}" type ="text/javascript" > </script > <script src ="{{ admin_static.url(filename='vendor/moment.min.js', v='2.9.0') }}" type ="text/javascript" > </script > <script src ="{{ admin_static.url(filename='vendor/select2/select2.min.js', v='3.5.2') }}" type ="text/javascript" > </script > {% if admin_view.extra_js %} {% for js_url in admin_view.extra_js %} <script src ="{{ js_url }}" type ="text/javascript" > </script > {% endfor %} {% endif %} {% endblock %} {% block tail %} {% endblock %} </body > </html >
修改 list.html
vim venv/lib/python2.7/site-packages/flask_admin/templates/bootstrap3/admin/model/list.html
list.html明细如下{% extends 'admin/master.html' %} {% import 'admin/lib.html' as lib with context %} {% import 'admin/static.html' as admin_static with context%} {% import 'admin/model/layout.html' as model_layout with context %} {% import 'admin/actions.html' as actionlib with context %} {% import 'admin/model/row_actions.html' as row_actions with context %} {% block head %} {{ super() }} {{ lib.form_css() }} {% endblock %} {% block body %} <div class ="panel panel-default" > <div class ="panel-body" > {% block title %}{% if admin_view.category %}{{ admin_view.category }} - {% endif %}{{ admin_view.name }}{% endblock %} </div > </div > {% block model_menu_bar %} <ul class ="nav nav-tabs actions-nav" > <li class ="active" > <a href ="javascript:void(0)" > {{ _gettext('List') }}{% if count %} ({{ count }}){% endif %}</a > </li > {% if admin_view.can_create %} <li > {%- if admin_view.create_modal -%} {{ lib.add_modal_button(url=get_url('.create_view', url=return_url, modal=True), title=_gettext('Create New Record'), content=_gettext('Create')) }} {% else %} <a href ="{{ get_url('.create_view', url=return_url) }}" title ="{{ _gettext('Create New Record') }}" > {{ _gettext('Create') }}</a > {%- endif -%} </li > {% endif %} {% if admin_view.can_export %} {{ model_layout.export_options() }} {% endif %} {% block model_menu_bar_before_filters %}{% endblock %} {% if filters %} <li class ="dropdown" > {{ model_layout.filter_options() }} </li > {% endif %} {% if can_set_page_size %} <li class ="dropdown" > {{ model_layout.page_size_form(page_size_url) }} </li > {% endif %} {% if actions %} <li class ="dropdown" > {{ actionlib.dropdown(actions) }} </li > {% endif %} {% if search_supported %} <li > {{ model_layout.search_form() }} </li > {% endif %} {% block model_menu_bar_after_filters %}{% endblock %} </ul > {% endblock %} {% if filters %} {{ model_layout.filter_form() }} <div class ="clearfix" > </div > {% endif %} {% block model_list_table %} <div class ="table table-striped table-bordered table-hover model-list" style ="white-space:nowrap" > <table id ="booboo_table" data-toggle ="table" data-show-columns ="true" data-show-footer ="true" > <thead > <tr > {% block list_header scoped %} {% if actions %} <th class ="list-checkbox-column" > <input type ="checkbox" name ="rowtoggle" class ="action-rowtoggle" title ="{{ _gettext('Select all records') }}" /> </th > {% endif %} {% block list_row_actions_header %} {% if admin_view.column_display_actions %} <th class ="col-md-1" data-field ="id" data-footer-formatter ="idFormatter" > </th > {% endif %} {% endblock %} {% for c, name in list_columns %} {% set column = loop.index0 %} {% if name in ["充值金额","充值不含税","充值税额","应收金额","应收不含税","应收税额","发票金额","不含税金额","税额","本月确认成本","本月确认收入", "累计应收金额" ,"累计应收不含税" ,"累计应收税额" ,"累计充值金额" ,"累计充值不含税" ,"累计充值税额" ,"累计发票金额" ,"累计发票不含税金额" ,"累计发票税额" ,"累计确认收入" ,"累计未确认收入不含税" ,"累计未索取发票金额"] %} <th data-field ="price" data-footer-formatter ="priceFormatter" class ="column-header col-{{c}}" > {% else %} <th class ="column-header col-{{c}}" > {% endif %} {% if admin_view.is_sortable(c) %} {% if sort_column == column %} <a href ="{{ sort_url(column, True) }}" title ="{{ _gettext('Sort by %(name)s', name=name) }}" > {{ name }} {% if sort_desc %} <span class ="fa fa-chevron-up glyphicon glyphicon-chevron-up" > </span > {% else %} <span class ="fa fa-chevron-down glyphicon glyphicon-chevron-down" > </span > {% endif %} </a > {% else %} <a href ="{{ sort_url(column) }}" title ="{{ _gettext('Sort by %(name)s', name=name) }}" > {{ name }}</a > {% endif %} {% else %} {{ name }} {% endif %} {% if admin_view.column_descriptions.get(c) %} <a class ="fa fa-question-circle glyphicon glyphicon-question-sign" title ="{{ admin_view.column_descriptions[c] }}" href ="javascript:void(0)" data-role ="tooltip" > </a > {% endif %} </th > {% endfor %} {% endblock %} </tr > </thead > {% for row in data %} <tr > {% block list_row scoped %} {% if actions %} <td > <input type ="checkbox" name ="rowid" class ="action-checkbox" value ="{{ get_pk_value(row) }}" title ="{{ _gettext('Select record') }}" /> </td > {% endif %} {% block list_row_actions_column scoped %} {% if admin_view.column_display_actions %} <td class ="list-buttons-column" > {% block list_row_actions scoped %} {% for action in list_row_actions %} {{ action.render_ctx(get_pk_value(row), row) }} {% endfor %} {% endblock %} </td > {%- endif -%} {% endblock %} {% for c, name in list_columns %} <td class ="col-{{c}}" > {% if admin_view.is_editable(c) %} {% set form = list_forms[get_pk_value(row)] %} {% if form.csrf_token %} {{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=form.csrf_token._value()) }} {% else %} {{ form[c](pk=get_pk_value(row), display_value=get_value(row, c)) }} {% endif %} {% else %} {{ get_value(row, c) }} {% endif %} </td > {% endfor %} {% endblock %} </tr > {% else %} <tr > <td colspan ="999" > {% block empty_list_message %} <div class ="text-center" > {{ admin_view.get_empty_list_message() }} </div > {% endblock %} </td > </tr > {% endfor %} </table > </div > <script > function idFormatter ( ) { return 'Total' } function nameFormatter (data ) { return data.length } function priceFormatter (data ) { var field = this .field return '$' + data.map (function (row ) { return +row[field].substring (1 ) }).reduce (function (sum, i ) { return sum + i }, 0 ) } </script > {% block list_pager %} {% if num_pages is not none %} {{ lib.pager(page, num_pages, pager_url) }} {% else %} {{ lib.simple_pager(page, data|length == page_size, pager_url) }} {% endif %} {% endblock %} {% endblock %} {% block actions %} {{ actionlib.form(actions, get_url('.action_view')) }} {% endblock %} {%- if admin_view.edit_modal or admin_view.create_modal or admin_view.details_modal -%} {{ lib.add_modal_window() }} {%- endif -%} {% endblock %} {% block tail %} {{ super() }} {% if filter_groups %} <div id ="filter-groups-data" style ="display:none;" > {{ filter_groups|tojson|safe }}</div > <div id ="active-filters-data" style ="display:none;" > {{ active_filters|tojson|safe }}</div > {% endif %} <script src ="{{ admin_static.url(filename='admin/js/filters.js', v='1.0.0') }}" > </script > {{ lib.form_js() }} {{ actionlib.script(_gettext('Please select at least one record.'), actions, actions_confirmation) }} {% endblock %}
操作记录 /alidata/fms-backup/venv/lib/python2.7/site-packages/flask_admin/templates/bootstrap3/admin (venv) [root@fms admin] 总用量 40 -rw-r--r-- 1 root root 1389 10月 20 20:01 actions.html -rw-r--r-- 1 root root 4030 10月 20 20:01 base.html drwxr-xr-x 3 root root 54 10月 20 20:01 file -rw-r--r-- 1 root root 67 10月 20 20:01 index.html -rw-r--r-- 1 root root 4129 10月 20 20:01 layout.html -rw-r--r-- 1 root root 8655 10月 20 20:01 lib.html -rw-r--r-- 1 root root 34 10月 20 20:01 master.html drwxr-xr-x 3 root root 219 10月 20 20:01 model drwxr-xr-x 2 root root 47 10月 20 20:01 rediscli -rw-r--r-- 1 root root 89 10月 20 20:01 static.html (venv) [root@fms admin] (venv) [root@fms admin] (venv) [root@fms admin] (venv) [root@fms admin] actions.html base.html base.html.bac file index.html layout.html lib.html master.html model rediscli static.html (venv) [root@fms admin] (venv) [root@fms model] 总用量 44 -rw-r--r-- 1 root root 705 10月 20 20:01 create.html -rw-r--r-- 1 root root 1447 10月 20 20:01 details.html -rw-r--r-- 1 root root 1070 10月 20 20:01 edit.html -rw-r--r-- 1 root root 410 10月 20 20:01 inline_field_list.html -rw-r--r-- 1 root root 153 10月 20 20:01 inline_form.html -rw-r--r-- 1 root root 2206 10月 20 20:01 inline_list_base.html -rw-r--r-- 1 root root 4145 10月 20 20:01 layout.html -rwxr-xr-x 1 root root 7615 10月 20 20:01 list.html drwxr-xr-x 2 root root 62 10月 20 20:01 modals -rw-r--r-- 1 root root 1726 10月 20 20:01 row_actions.html (venv) [root@fms model] /alidata/fms-backup/venv/lib/python2.7/site-packages/flask_admin/templates/bootstrap3/admin/model (venv) [root@fms model] (venv) [root@fms model] (venv) [root@fms model]
demo <!doctype html > <html lang ="en" > <head > <title > Bootstrap Table Examples</title > <meta charset ="utf-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="description" content ="An extended Bootstrap table with radio, checkbox, sort, pagination, and other added features." > <meta name ="keywords" content ="table, bootstrap, bootstrap plugin, bootstrap resources, bootstrap table, jQuery plugin" > <meta name ="author" content ="Zhixin Wen, and Bootstrap table contributors" > <link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" > <link rel ="stylesheet" href ="https://unpkg.com/@fortawesome/fontawesome-free@5.12.1/css/all.min.css" > <link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/default.min.css" > <link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/hint.css/2.5.1/hint.min.css" > <link rel ="stylesheet" href ="assets/css/docs.min.css" > <link rel ="stylesheet" href ="assets/css/template.css?v=131" > <script type ="text/javascript" async ="" src ="https://www.google-analytics.com/analytics.js" > </script > <script src ="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity ="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin ="anonymous" > </script > <script src ="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" > </script > <script src ="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.2/sprintf.min.js" > </script > <script src ="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js" > </script > <script src ="https://cdn.jsdelivr.net/npm/marked/marked.min.js" > </script > <script src ="https://unpkg.com/flexibility@2.0.1/flexibility.js" > </script > <script src ="assets/js/template.js?v=131" > </script > <script async ="" src ="https://www.googletagmanager.com/gtag/js?id=UA-132747866-1" > </script > <script > window .dataLayer = window .dataLayer || [] function gtag ( ) {window .dataLayer .push (arguments )} gtag ('js' , new Date ()) gtag ('config' , 'UA-132747866-1' ) </script > <link href ="https://unpkg.com/bootstrap-table@1.18.0/dist/bootstrap-table.min.css" rel ="stylesheet" > <script src ="https://unpkg.com/bootstrap-table@1.18.0/dist/bootstrap-table.min.js" > </script > <script id ="_carbonads_projs" type ="text/javascript" src ="https://srv.carbonads.net/ads/CK7DL2J7.json?segment=placement:bootstrap-tablecom& callback=_carbonads_go" > </script > </head > <body > <div class ="container" > <div class ="header-wrapper" > <div class ="title-desc" > <p class ="bd-lead" > <p > Use <code > showFooter</code > option to show the summary footer row.</p > </p > </div > <div id ="example" > <script > init ({ title : 'Show Footer' , desc : 'Use `showFooter` option to show the summary footer row.' , links : ['bootstrap-table.min.css' ], scripts : ['bootstrap-table.min.js' ] }) </script > <table id ="table" data-toggle ="table" data-height ="460" data-show-columns ="true" data-show-footer ="true" data-url ="json/data1.json" > <thead > <tr > <th data-field ="id" data-footer-formatter ="idFormatter" > ID</th > <th data-field ="name" data-footer-formatter ="nameFormatter" > Item Name</th > <th data-field ="price" data-footer-formatter ="priceFormatter" > Item Price</th > </tr > </thead > </table > <script > function idFormatter ( ) { return 'Total' } function nameFormatter (data ) { return data.length } function priceFormatter (data ) { var field = this .field return '$' + data.map (function (row ) { return +row[field].substring (1 ) }).reduce (function (sum, i ) { return sum + i }, 0 ) } </script > </div > <script src ="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity ="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin ="anonymous" > </script > <script src ="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity ="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin ="anonymous" > </script > <script src ="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity ="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin ="anonymous" > </script > <script > $.browser = {} </script > <script src ="https://cdn.jsdelivr.net/npm/jquery-hashchange@2.0.0/jquery.ba-hashchange.min.js" > </script > <script src ="https://cdn.jsdelivr.net/npm/algoliasearch@3.32.0/dist/algoliasearchLite.min.js" > </script > <script src ="https://cdn.jsdelivr.net/npm/instantsearch.js@3.0.0/dist/instantsearch.production.min.js" > </script > <script src ="assets/js/docs.min.js" > </script > <script src ="assets/js/index.js?v=131" > </script > </div > </div > </body > </html >