先上代码:https://github.com/knotgd/bootstrap_flask
一、什么是Bootstrap
Bootstrap,来自 Twitter,是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。
二、什么是Flask
Flask 是一个微型的 Python 开发的 Web 框架,基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用BSD授权。 Flask也被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。
三、为什么整合开发
主要看中Bootstrap响应式布局,方便简洁开发;还可以使用模板继承;组件丰富满足大部分需求。Flask轻量级开发迅速,可以根据产品需求,迅速产出demo,或是进行数据展示与交互。
四、整合示例
4.1 目录结构
- apps目录:根据功能或是业务进行的模块拆分,主目录下有个views模块作为视图汇总,在views中注册所有分功能下的蓝图。
- core目录:主要负责存放业务抽象框架和常量定义的内容(目前空)。
- ui目录:主要存放html和css等前端展示的文件
- run:主要负责demo服务启动。
4.2 views整合蓝图
views代码如下:
# @Time : 2020/7/13
# @Author : 大太阳小白
# @Software: PyCharm
# @blog:https://blog.csdn.net/weixin_41579863
from flask import Flask
from apps.index.view import index_blueprint
from apps.form.view import form_blueprint
from apps.ui_fitures.view import fitures_blueprint
from apps.widgets.view import widgets_blueprint
from apps.charts.view import chart_blueprint
from apps.tables.view import table_blueprint
from apps.pages.view import pages_blueprint
app = Flask(__name__, template_folder="..\\ui\\templates", static_folder="..\\ui\\static")
app.register_blueprint(index_blueprint)
app.register_blueprint(form_blueprint)
app.register_blueprint(fitures_blueprint)
app.register_blueprint(widgets_blueprint)
app.register_blueprint(chart_blueprint)
app.register_blueprint(table_blueprint)
app.register_blueprint(pages_blueprint)
views汇总和注册了所有蓝图,并重新指定了模板和静态文件位置。
表格功能view代码如下:
# @Time : 2020/7/13
# @Author : 大太阳小白
# @Software: PyCharm
# @blog:https://blog.csdn.net/weixin_41579863
from flask import Blueprint
from flask import render_template
table_blueprint = Blueprint('table', __name__)
@table_blueprint.route('/table', methods=['GET', 'POST'])
def tables_components():
return render_template('basic_table.html', )
该view定义了蓝图和相应的映射
4.3 bootstrap继承
通用模块目录结构
header.html 定义了页面头部标题信息
footer.html 定义了页面尾部信息
sidebar.html 定义了页面左边目录信息
base.html 引用了上述三个页面模板,并增加css、js基础代码,在此基础上还定义了自定义区域。
base.html代码如下:
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<title>{% block title %}demo{% endblock %}</title>
<!-- CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/bootstrap-theme.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/elegant-icons-style.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/font-awesome.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/fullcalendar.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/jquery-jvectormap-1.2.2.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/jquery-ui-1.10.4.min.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/line-icons.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/owl.carousel.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/style.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/style-responsive.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/widgets.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='css/xcharts.min.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='assets/fullcalendar/fullcalendar/bootstrap-fullcalendar.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='assets/fullcalendar/fullcalendar/fullcalendar.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
<link href="{{ url_for('static', filename='assets/jquery-easy-pie-chart/jquery.easy-pie-chart.css') }}" target="_blank" rel="external nofollow" rel="stylesheet">
{% block css %}
{% endblock %}
<!-- JS -->
<script src="{{ url_for('static', filename='js/jquery.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery-ui-1.10.4.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery-1.8.3.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery-ui-1.9.2.custom.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.scrollTo.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.nicescroll.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.sparkline.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/owl.carousel.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/fullcalendar.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/calendar-custom.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.rateit.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.customSelect.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/scripts.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/sparkline-chart.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/easy-pie-chart.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery-jvectormap-1.2.2.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery-jvectormap-world-mill-en.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/xcharts.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.autosize.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.placeholder.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/gdp-data.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/morris.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/sparklines.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/charts.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static', filename='js/jquery.slimscroll.min.js')}}" type="text/javascript"></script>
{% block js %}
{% endblock %}
</head>
<body>
<section id="container">
{% include "common/header.html" %}<!--引入网页的头部模板-->
{% include "common/sidebar.html" %}<!--引入网页的侧边模板-->
{% block content %}<!--自定义模板区域-->
{% endblock %}
</section><!--/row-->
{% include "common/footer.html" %}<!--引入网页的底部模板-->
</body>
</html>
其他页面只需要继承base.html基础模板,然后在添加自定义区域的内容即可。
例如widgets.html 页面
{% extends "common/base.html" %}<!--继承基础模板-->
{% block content %}<!--自定义模板区域-->
<!--main content start-->
<section id="main-content">
<section class="wrapper">
<div class="row">
<div class="col-lg-12">
<h3 class="page-header"><i class="icon_genius"></i> Widgets</h3>
<ol class="breadcrumb">
<li><i class="fa fa-home"></i><a href="index.html" target="_blank" rel="external nofollow" >Home</a></li>
<li><i class="icon_genius"></i>Widgets</li>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<section class="panel">
<header class="panel-heading">
Basic items
</header>
<ul class="list-group">
<li class="list-group-item">Lorem ipsum dolor sit amet</li>
<li class="list-group-item">Praesent tempus eleifend risus</li>
<li class="list-group-item">Praesent tempus eleifend risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</section>
</div>
<div class="col-lg-4">
<section class="panel">
<header class="panel-heading">
Linked items
</header>
<div class="list-group">
<a class="list-group-item " href="#" target="_blank" rel="external nofollow" >
Lorem ipsum dolor sit amet
</a>
<a class="list-group-item active" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >Praesent tempus eleifend risus</a>
<a class="list-group-item" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >Praesent tempus eleifend risus</a>
<a class="list-group-item" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >Porta ac consectetur ac</a>
<a class="list-group-item" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >Vestibulum at eros</a>
<a class="list-group-item" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >Vestibulum at eros</a>
</div>
</section>
</div>
<div class="col-lg-4">
<section class="panel">
<header class="panel-heading">
Custom content
</header>
<div class="list-group">
<a class="list-group-item " href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<a class="list-group-item active" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<a class="list-group-item" href="javascript:;" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
</div>
</section>
</div>
</div>
<!-- page end-->
</section>
</section>
<!--main content end-->
</section>
<!-- container section end -->
{% endblock %}
4.4 数据交互
在pages目录的test页面中,实现了两种交互方式:
一种方式是页面请求时候直接将数据注入到页面变量里:
@pages_blueprint.route('/pages/test', methods=['GET', 'POST'])
def test_service():
num = '-----'
if request.method == 'POST':
num = request.form['num']
data = ["从后台传来的数据"+num]
return render_template('test.html', data=data)
前段只要解析data变量,就可以展示数据,形如:
<script>
var init_data = {{data | tojson}}
init_show(init_data)
function init_show(data) {
for (let i = 0; i < data.length; i++) {
$("#show").append("<div class='alert alert-block alert-danger fade in'> <button class='close close-sm'" +
" type='button' data-dismiss='alert'> <i class='icon-remove'></i> </button>" + data[i] + " </div>")
}
}
</script>
第二种方式
使用ajax局部前端代码如下:
function test() {
var form = new FormData(document.getElementById("test_form"));
$.ajax({
url: "/pages/test/ajax",
type: "POST",
data: form,
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
console.log(data)
init_show(data)
}
,
error: function (e) {
}
})
}
4.5 服务启动
run.py 是项目启动入口
前端页面代码是从模板网站上下载的,所以可能看着会眼熟,根据上述思路进行了整合,每个页面展示了不同的组件和呈现方式,囊括了多种样式,感觉还是不错的。