使用Flask框架、Mysql在Pycharm搭建可视化环境
1 from flask import Flask
2
3 app = Flask(__name__)
4
5 @app.route('/')
6 def hello_world():
7 return 'Hello World!'
8
9 if __name__ == '__main__':
10 app.run(host='0.0.0.0',port=9000)
第1行,引入Flask类,Flask类实现了一个WSGI应用
第3行,app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__。让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录。
第5-7行,使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。
处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello_world。
第10行,执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000。 而我们对虚拟机做的端口转发端口是9000,所以需要制定host和port参数,0.0.0.0表示监听所有地址,这样就可以在本机访问了。服务器启动后,会调用werkzeug.serving.run_simple进入轮询,默认使用单进程单线程的werkzeug.serving.BaseWSGIServer处理请求,实际上还是使用标准库BaseHTTPServer.HTTPServer,通过select.select做0.5秒的“while TRUE”的事件轮询。当我们访问“http://127.0.0.1:9000/”,通过app.url_map找到注册的“/”这个URL模式,就找到了对应的hello_world函数执行,返回“hello world!”,状态码为200。如果访问一个不存在的路径,如访问“http://127.0.0.1:9000/a”,Flask找不到对应的模式,就会向浏览器返回“Not Found”,状态码为404
整体步骤:
第一部分,初始化:
所有的Flask都必须创建程序实例,web服务器使用wsgi协议,把客户端所有的请求都转发给这个程序实例。
程序实例是Flask的对象,一般情况下用如下方法实例化。Flask类只有一个必须指定的参数,即程序主模块或者包的名字,__name__是系统变量,该变量指的是本py文件的文件名
from flask import Flask
app = Flask(__name__)
第二部分,路由和视图函数:
客户端发送url给web服务器,web服务器将url转发给flask程序实例,
程序实例需要知道对于每一个url请求启动那一部分代码,所以保存了一个url和python函数的映射关系。
处理url和函数之间关系的程序,称为路由。在flask中,定义路由最简便的方式,是使用程序实例的app.route装饰器,把装饰的函数注册为路由
.route('/')
def hello_world():
return
注意:这里的视图函数就是指def hello_world(),可以参见下面的案列里的def index()
第三部分:程序实例用run方法启动flask集成的开发web服务器
# __name__ == '__main__'是python常用的方法,表示只有直接启动本脚本时候,才用app.run方法
# 如果是其他脚本调用本脚本,程序假定父级脚本会启用不同的服务器,因此不用执行app.run()
# 服务器启动后,会启动轮询,等待并处理请求。轮询会一直请求,直到程序停止。
if __name__ == '__main__':
print('dd',__name__)
app.run()
如上述代码所示,app是flask的实例,功能就是接受来自web服务器的请求,
浏览器将请求给web服务器,web服务器将请求给app ,
app收到请求,通过路由找到对应的视图函数,然后将请求处理,得到一个响应response
然后app将响应返回给web服务器,web服务器返回给浏览器,
浏览器展示给用户观看,流程完毕。
实例: 简单的柱状图绘制
# -*- coding: utf-8
# @Time : 2020/11/7 10:25
# @Author : ZYX
# @File : bar01.py
# @software: PyCharm
# 1.导包
from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
# 2.创建flask应用对象
app = Flask(__name__)
# 3.配置sqlalchemy的参数
class Config(object):
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/visiable"
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 4.将参数传入flask对象
app.config.from_object(Config)
# 5.利用SQLAlchemy中传入app参数实例化Flask对象
db = SQLAlchemy(app)
# 6.创建数据库模型制作表
class sheets(db.Model):
__tablename__ = "bar01"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(64),unique=True)
age = db.Column(db.Integer())
# 使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。
# 处理URL和视图函数的关系的程序就是路由,这里的视图函数就是index。
@app.route("/")
def index():
sheets_list = sheets.query.all()
# 说白了,其实render_template的功能是对先引入index.html,
# 同时根据后面传入的参数,对html进行修改渲染 --- 处理数据
return render_template("bar01.html", sheets=sheets_list)
if __name__ == '__main__':
db.drop_all() # 若有表先清除
db.create_all() # 创建表
c1 = sheets(name="a",age=18) # 编写数据
c2 = sheets(name="b", age=22)
c3 = sheets(name="c", age=20)
c4 = sheets(name="e", age=17)
c5 = sheets(name="f", age=23)
c6 = sheets(name="g", age=15)
db.session.add_all([c1,c2,c3,c4,c5,c6]) # 向表中插入数据
db.session.commit() # 利用session进行提交
app.run(debug=True) # 运行
<!DOCTYPE html>
<html lang="en"style="height:">
{#设置页面比例#}
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<bodystyle="height:">
<div id="container"style="height:"></div>
{#设置盒子模型比例#}
<script type="text/javascript" src="../static/echarts%20(1).js"></script>
<script type="text/javascript">// 1.实例化对象
var dom = document.getElementById("container");
var myecharts = echarts.init(dom);
// 2.从数据库中取出数据
var data1 = [{% for item in sheets %}'{{ item.name }}',{% endfor %}];
var data2 = [{% for item in sheets %}'{{ item.age }}',{% endfor %}];
// 3.配置参数
var option = null;
option = {
color:['#3398DB'], // 颜色
tooltip:{ // 提示框组件
show:true,
trigger:'axis', // 触发类型
axisPointer:{ // 坐标轴指示器配置项
type:'shadow'
}
},
grid:{
left:'3%',
right:'4%',
top:'3%',
bottom:'3%',
containLabel:true // grid 区域是否包含坐标轴的刻度标签
},
xAxis:[ // x轴
{
type: 'category', // 类型 --- 类别型
data:data1, // 数据
axisTick:{ // x轴刻度
alignWithLabel:true // 类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。
}
}
],
yAxis:[ // y轴
{
type:'value'
}
],
series:[ // 系列列表。每个系列通过 type 决定自己的图表类型
{
name:'直接访问', // 系列名称,用于tooltip的显示,legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。
type:'bar', // 类型 --- 柱状图
data:data2,
borderWidth:'60%'
}
]
};
// 4.将配置的参数传递给echarts对象
if (option && typeof option == 'object'){
myecharts.setOption(option);
}</script>
</body>
</html>