- 你还可以尝试在地址栏中输入:http://127.0.0.1:5000?name=小明,观察一下会发生什么吧!
Hello World 执行的逻辑
当我们使用 flask run
命令启动 hello_world 项目之后,该项目就变成了一个服务,执行在本机(127.0.0.1
指本地,等同于localhost
),它监听本机的5000
端口,实时查看是否有新的请求传来(就像名叫hello_world
的富二代,住在地址是127.0.0.1
的大别墅中,对着编号为5000
的窗口喊,有人来找我玩吗?)。
我们在浏览器地址栏中输入http://127.0.0.1:5000/
后,点击回车,就利用浏览器向hello_world服务发送了一个请求。
服务器在接收到我们的请求后,就会调用对应的函数为我们提供服务,这个函数在Flask中被称为视图,例如hello_world项目中的hello
方法:
def hello():
name = request.args.get("name", "World")
return f'Hello, {escape(name)}!'
虽然本例中只有一个hello
视图,但是一个服务通常具备许多提供不同功能的视图,每当用户通过浏览器发送请求的时候,服务器都要从众多视图中准确的找到我们想要的那个。这种将请求和视图(也就是函数)一一对应起来的程序,被称为路由(映射),也就是hello_world中的@app.route('/')
。
一旦Flask中的函数头上被放置了路由,那么他就从普通函数变成了视图,用于处理我们的请求。
现在还有一个问题,我们是如何表达我们想要的服务的呢?这就是URL,也就是我们在浏览器地址栏中输入 http://127.0.0.1:5000
后面的 /
(地址后不输入任何内容,默认就是 /
,所以我们直接输入http://127.0.0.1:5000
效果是一样的)。
到这里,我们就可以简单的总结以上工作:
首先,我们通过浏览器向hello_world服务器发送了一个请求,请求地址是127.0.0.1:5000
,请求的内容是/
。
hello_world服务器在接收到我们的请求 /
后,通过路由找到 /
对应的服务内容是hello()
函数,然后就调用hello()
函数。
hello()
函数在处理完我们的请求后,向我们返回了请求的结果,也就是显示Hello World的页面。
Hello World 代码解读
当我们了解了整个Flask应用的运行逻辑(B/S架构的执行逻辑),再回头看Flask官方的解读可能会有更多收获,针对Hello World应用,官方文档代码解释如下
-
首先我们导入了 Flask 类。 该类的实例将会成为我们的 WSGI 应用(整个hello_world服务本质上就是一个Flask类的实例)。
-
接着我们创建一个该类的实例。第一个参数是应用模块或者包的名称。如果你使用 一个单一模块(就像本例),那么应当使用
__name__
,因为名称会根据这个 模块是按应用方式使用还是作为一个模块导入而发生变化(可能是__main__
, 也可能是实际导入的名称)。这个参数是必需的,这样 Flask 才能知道在哪里可以 找到模板和静态文件等东西。更多内容详见 Flask 文档。 -
然后我们使用
route()
装饰器来告诉 Flask 触发函数的 URL(告诉Flask什么样的URL需要调用这个函数) 。 -
函数名称被用于生成相关联的 URL 。函数最后返回需要在用户浏览器中显示的信息。
提示:
当我们使用
http://127.0.0.1:5000?name=xiaoming
访问hello_world服务的时候,就为服务器提供了一个参数,参数名是name
,参数值是xiaoming
。在服务端,通过request.args.get("name", "World")
可以取得参数name
的值,如果没有找到name
(也就是我们没有提供),那么就返回默认值World
。
显然,一个只会问好的服务并不是我们想要的,想要更酷炫的内容就需要为hello_world添加更多的能力。
为了彰显自己的丰功伟绩,我决定为自己搭建一个个人主页,用以记录本人曾经和以后的光辉时刻。
下面,我将从hello_world出发,逐步搭建出一个只有一个页面的个人主页。
Flask本身非常的轻量(简单),可以通过安装插件的方式,使用各种神奇的功能,为了降低代码量,下面将使用 bootstrap-flask插件编写前端代码。
市面上还有一个 flask-bootstrap
插件,这是一个老的版本,我们这里使用最新的bootstrap-flask
。
templates 和 static 文件夹
直接返回字符串的方式过于简陋,我们需要使用HTML
页面展示更复杂的内容。在Flask中默认存放HTML
页面的位置是根目录下的 templates
文件夹,对应的存放静态文件(例如图片、css、js文件)的目录是static
。我们需要创建这两个文件夹。
展示个人信息的HTML
页面需要放置在 templates
下,我将其命名为 me.html
如此,整个加强版的hello_world项目框架就搭建完成了,这个项目目录树如下:
hello_world # 项目根目录
├── app.py # 代码文件
├── static/ # 静态文件夹
├── templates/ # 模板文件夹、存放HTML
│ └── me.html # 个人主页
└── venv/ # 虚拟环境
安装bootstrap-flask插件
首先,我们需要在虚拟环境中安装bootstrap-flask
插件,在虚拟环境激活状态先执行:
(venv)~/hello_world$ pip install bootstrap-flask
配置bootstrap-flask插件
在app.py
中配置bootstrap-flask
插件只需要两步:
- 从bootstrap-flask导入Bootstrap类,如下:
from flask_bootstrap import Bootstrap5
bootstrap-flask
插件中有多个Bootstrap类,如Bootstrap、Bootstrap4和Bootstrap5,其中Bootstrap对应版本3,Bootstrap4对应版本4,Bootstrap5对应版本5。
之所以选择Bootstrap5,自然是因为我觉得一个拥有个人主页的我能驾驭~
- 创建Bootstrap实例
在app = Flask(__name__)
语句后插入:
bootstrap = Bootstrap5(app)
到这里就完成了bootstrap-flask
插件的配置,你的app.py
文件应该如下:
# save this as app.py
from ensurepip import bootstrap
from flask import Flask, escape, request
from flask_bootstrap import Bootstrap5
app = Flask(__name__)
bootstrap = Bootstrap5(app)
@app.route('/')
def hello():
name = request.args.get("name", "World")
return f'Hello, {escape(name)}!'
HTML引入 bootstrap-flask
Flask的HTML页面使用了Jinja2模板引擎,由于本文只是演示Flask的简单用法,这里就不详细介绍引擎的使用方法了,如果有学习的兴趣,可以追更本系列,后继文章会围绕Flask介绍全栈的知识点。
在me.html
引入bootstrap
之前,我们需要先写一个HTML文件的框架,如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{{ title }}</title>
</head>
<body>
<!-- 主体内容 -->
<div id="main" class="container">
</div>
</body>
</html>
引入bootstrap-flask
需要引入css
和js
文件,步骤如下:
- 引入
css
文件,在<head>
标签中插入以下代码:
{{ bootstrap.load_css() }}
- 引入
js
文件,在</body>
标签前插入如下代码:
{{ bootstrap.load_js() }}
配置完成后,me.html
的内容应该和下面相同:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- 引入css文件 -->
{{ bootstrap.load_css() }}
<title>{{ title }}</title>
</head>
<body>
<!-- 主体内容 -->
<div id="main" class="container">
</div>
<!-- 引入js文件 -->
{{ bootstrap.load_js() }}
</body>
</html>
修改路由和视图
正常情况下一个网站的 ‘/’
URL用于展示网站的主页,当前,我们还没有其他页面,可以先让/
指向个人主页。于此同时,新增路由/me
。
改动步骤如下:
-
在
hello()
函数上面添加路由/me
-
修改
hello()
函数名称为me()
-
修改返回值,渲染对应的
me.html
@app.route('/')
@app.route('/me')
def me():
return render_template('me.html',title="魏大大的个人主页")