Flask Web框架的使用-静态文件和模版
- 一、前言
- 二、引言
- 三、Web 框架简介
- 1.什么是Web框架
- 2.常用的 Web 框架
- Flask
- Django
- Bottle
- Tornado
- 四、Flask Web框架的使用
- 1.安装虚拟环境
- 安装Virtualen
- 创建虚拟环境
- 激活虚拟环境
- 2.安装Flask
- 3.第一个Flask 程序
- 4.开启调试模式
- 5.路由
- 变量规则
- 构造 URL
- HTTP 方法
- 6.静态文件
- 7.模版
- 渲染模版
- 变量
- 控件
一、前言
- 个人主页: ζ小菜鸡
- 大家好我是ζ小菜鸡,让我们一起来学习Flask Web框架的使用(合集)。
- 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)
二、引言
如果你要从零开始建立了一些网站,可能会注意到你不得不一次又一次地解决一些相同的问题。这样做是令人厌烦的,并且违反了良好编程的核心原则之一——DRY(不要重复自己)。
有经验的Web开发人员在创建新站点时也会遇到类似的问题。当然,总有一些特殊情况会因网站而异,但是大多数据情况下,开发人员通常需要处理四项任务——数据的创建、读取、更新和删除,也称为CRUD。幸运的是,通过Web框架很好的解决了这些问题。
三、Web 框架简介
1.什么是Web框架
Web框架是用来简化Web开发的软件框架。框架的存在时为了避免你重新发明轮子,并且在创建一个新的网站时帮助减轻一些开销。典型的框架提供了如下常用的功能:
- 管理路由
- 访问数据库
- 管理会话和Cookie
- 创建模板来显示HTML
- 促进代码的重用
事实上,框架根本就不是什么新的东西,它只是一些能够实现常用功能的Python文件。我们可以把框架看作是工具的集合,而不是特定的东西。框架的存在使得建立网站更快、更容易。框架还促进了代码的重用。
2.常用的 Web 框架
WSGI(服务器网关接口),它是Web服务器和Web应用程序之间的一种简单而通用的接口。也就是说,只要遵循 WSGI 接口规则,就可以自主开发Web框架。所以,各种开源 Web 框架至少有上百个,关于Python框架优劣的讨论也乃再继续。作为初学者,应该选择一些主流的框架来学习使用。这是因为主流框架文档齐全,技术积累较多、社区繁盛,并且能得到更好的支持。下面介绍几种Python的主流Web框架。
Flask
Flask是一个轻量级Web应用框架。它的名字暗示了它的含义,它基本上就是一个微型的胶水框架,它把Werkzeug 和 Jinja粘合在了一起,所以它很容易扩展。Flask也有许多的扩展可以供你使用,Flask也有一群忠诚的粉丝和不断增加的用户群,它有一份很完善的文档,甚至还有一份垂手可得的常见范例。Flask很容易使用,你只需要几行代码就可以写出来一个“hello world”。
Django
这可能是最广为人知和使用最广的Python Web 框架了。Django 有世界上最大的社区,最多的包。它的文档非常完善,并且提供了一站式的解决方案,包括缓存、ORM、后台管理、验证、表单处理等,使得开发复杂的数据库驱动的网站变得简单。但是,Django系统耦合度较高,替换掉内置的功能时比较麻烦。
Bottle
这个框架相对来说比较新。Bottle才是名副其实的微框架——它只有大约4500行代码。它除了Python标准库以外没有任何其他的依赖,甚至它还有自己独特的一点儿模板语言。Bottle的文档很详细并且抓住了事物的实质。它很像Flask,也使用了装饰器定义路径。
Tornado
Tornado不单是个框架,还是Web服务器。它一开始是为了FriendFeed 而开发的,后来在2009年的时候也为了Facebook 提供使用。它是为了解决实时服务而诞生的。为了做到这一点,Tornado使用了异步非阻塞IO技术,所以它的运行速度非常快。
以上4种框架各有优劣,使用时需要根据自身的应用场景选择合适自己的Web框架。
四、Flask Web框架的使用
Flask 依赖两个外部库:Werkzeug 和 Jinja2。Werkzeug是一种WSGI(在Web 应用和多种服务之间的标准Python接口)工具集。所以,在安装Flask之前,需要安装这两个外部库。而最简单的方式就是使用Virtualenv创建虚拟环境。
1.安装虚拟环境
安装Flask 最便捷的方式是使用虚拟环境。Virtualenv 为每个不同的项目提供一份Python安装。它并没有真正安装多个Python副本,但是它确实提供了一种巧妙的方式来让各个项目环境保持独立。
安装Virtualen
Virtualen 的安装非常简单,可以使用如下命令进行:
pip install virtualenv
安装完成后,可以使用如下的命令检测Virtualenv版本:
virtualenv --version
如果运行效果如下图所示,则说明安装成功了。
创建虚拟环境
下一步是使用Virtualenv 命令在当前文件夹中创建Python虚拟环境。这个命令只有一个必须的参数,即虚拟环境的名字。创建虚拟环境后,当前文件夹中会出现一个子文件夹,名字就是上述命令中指定的参数,与虚拟环境相关的文件都保存这个子文件夹中。按照惯例,一般虚拟环境会被命名为crawl。运行如下命令:
virtualenv crawl
运行完成后,在运行的目录下,会新曾一个crawl文件夹,它保存一个全新的虚拟环境,其中有一个私有的Python解释器,如下图所示:
打开文件夹后,出现:
激活虚拟环境
返回到cmd中,我们还是一样的,输入cd crawl-env/Scripts,如下图所示:
继续输入activate就可以开启虚拟环境了,如下图所示:
2.安装Flask
大多数Python 包都是使用pip 实用工具安装,使用Virtualenv 创建虚拟环境时会自动安装pip。激活虚拟环境后,pip所在的路径会被添加进PATH。使用如下命令安装Flask:
pip install flask
运行如下图所示:
完成安装后,可以通过如下命令查看所有安装包:
pip list --format columns
运行结果如下图所示:
从上图可以看到,已经成功安装了Flask,并且也安装了Flask 的2个外部依赖库:Werkzeug 、Jinja2。
3.第一个Flask 程序
一切准备就绪,现在我们开始编写第一个Flask,由于是第一个Flask 程序,当然要从最简单的 “Hello World!”开始。
实例:输出“Hello World!”
在venv同级目录下,创建一个Flask_test.py 文件,代码如下:
from flask import Flask # 导入flask
app = Flask(__name__) # 创建Flask对象
@app.route("/")
def hello_world():
return "Hello world!"
if __name__ == "__main__":
app.run()
运行Flask_test.py 文件,运行效果如下图所示:
然后再浏览器中,然后输入网址“http://127.0.0.1:5000”,运行效果如下图所示:
那么,这段代码做了什么?
【1】首先,我们导入了Flask 类,这个类的实例将会是我们的WSGI应用程序。
【2】接下来,我们创建一个该类的实例,第一个参数是应用模块或者包的名称。如果你使用单一的模块(如本例),你应该使用“__name__
”,因为模块的名称将会因其作为单独应用启动还是作为模块导入而有所不同(“__main__
”或实际的导入名)。这是必须的,这样Flask才知道到哪去找模板、静态文件等等。
【3】然后,我们使用route()装饰器告诉Flask什么样的URL能出发我们的函数。
【4】这个函数的名字也在生成URL时被特定的函数采用,这个函数返回我们想要显示在用户浏览器中的信息。
【5】最后我们用run()函数来让应用运行在本地服务器上。其中“if __name__ == "__main__":
”确保服务只会在该脚本被Python解释器直接执行的时候才会运行,而不是作为模块导入的时候。
多学两招:
关闭服务器,可以直接按<ctrl+C>键。
4.开启调试模式
虽然run() 方法适用于启动本地的开发服务器,但是每次修改代码后都要手动重启它。这样并不够优雅,而且Flask 可以做到更好。如果你启用了调试支持,服务器会在代码修改后自动重新载入,并在发生错误时提供一个相当有用的调试器。
有两种途径来启用调试模式。一种是直接在应用对象上设置:
app.debug = True
app.run()
另外一种是作为run方法的一个参数传入:
app.run(debug = True)
两种方法的效果完全相同。
5.路由
客户端(如Web浏览器)把请求发送给Web服务器,Web服务器再把请求发送给Flask程序实例。程序实例需要知道对每个URL请求运行了那些代码,所以保存了一个URL到Python函数的映射关系。处理URL和函数之间关系的程序称为路由。
在Flask 程序中定义路由的最简便方式,是使用程序实例提供的app.route 修饰器,把修饰器的函数注册为路由。下面的例子说明了如何使用这个修饰器声明路由器:
@app.route("/")
def hello_world():
return "Hello world!"
说明:
修饰器是Python语言的标准特性,可以使用不同方式修改函数的行为。惯常用法是使用修饰器把函数注册为事件的处理程序。
但是,不仅如此!你可以构造含有动态部分的URL,也可以在一个函数上附着多个规则。
变量规则
要给URL添加变量部分,你可以把这些特殊的字段标记为<variable_name>
,这部分将会作为命名参数传递到你的函数。规则可以用<converter.variable_name>
指定一个可选的转换器。
示例:根据参数输出相应的信息
创建02文件夹,在该文件夹下创建 add-params.py 文件,添加如下代码:
from flask import Flask # 导入flask
app = Flask(__name__) # 创建Flask对象
@app.route("/user/<username>")
def show_user_profile(username):
# 显示该用户的用户信息
return "User %s" % username
@app.route("/post/<int:post_id>")
def show_post(post_id):
# 根据ID显示文章,ID是正型数据
return "Post %d" % post_id
if __name__ == "__main__":
app.run(debug = True)
上述代码中使用了转换器。它有下面几种:
【1】int: 接收整数。
【2】float: 同int,但是接收浮点数。
【2】path: 和默认的相似,但也接收斜线。
运行add-params.py ,在浏览器中将地址修改为“http://127.0.0.1:5000/user/小菜鸡
”,显示效果,如下图所示:
然后将地址修改为"http://127.0.0.1:5000/post/2"
,显示效果,如下图所示:
构造 URL
如果 Flask 能匹配 URL ,那么 Flask 可以生成它们吗?当然可以。你可以用url_for()
来给指定的函数构造 URL。它接受函数名作为第一个参数,也接受对应 URL 规则的变量部分的命名参数。未知变量部分会添加到 URL 末尾作为查询参数。
示例:使用 url_for() 函数获取 URL 信息
在示例“根据参数输出信息” 的基础上添加如下代码:
from flask import Flask, url_for # 导入flask
app = Flask(__name__) # 创建Flask对象
# 省略其余代码
@app.route("/url/")
def get_url():
# 根据ID显示文章,ID是正型数据
return url_for("show_post", post_id=2)
if __name__ == "__main__":
app.run(debug = True)
运行上述代码,设置“/url/”
路由,访问该路由时,返回“show_post” 函数信息。运行结果如下所示:
HTTP 方法
HTTP (与 Web应用会话的协议)有许多不同的访问URL方法。默认情况下,路由只回应 GET
请求,但是通过 route()
装饰器传递 methods 参数可以改变这个行为。例如:
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST": # 判断HTTP请求方式
do_the_login()
else:
show_the_login_form()
HTTP 方法(也经常被叫作“谓词”)告知服务器,客户端相对请求的页面做些什么。常见的方法,如下表所示:
方法名 | 说明 |
GET | 浏览器告知服务器:只获取页面上的信息并发给我。这是最常用的方法。 |
HEAD | 浏览器告诉服务器:欲获取信息,但是只关心消息头。应用应像处理GET请求一样来处理它,但是不分发实际内容。在 Flask中你完全无须人工干预,底层的Werkzeug 库已经替你处理好了。 |
POST | 浏览器告诉服务器:想在URL上发布新信息。并且,服务器必须确保数据已存储且仅存储一次。这是HTMI表单通常发送数据到服务器的方法。 |
PUT | 类似 POST,但是服务器可能触发了存储过程多次,多次覆盖掉旧值。你可能会问这有什么用?当然这是有原因的。考虑到传输中连接可能会丢失,在这种情况下浏览器和服务器之间的系统可能安全地第二次接收请求,而不破坏其他东西。因为POST它只触发次,所以用 POST 是不可能的。 |
DELETE | 删除给定位置的信息。 |
OPTIONS | 给客户端提供一个敏捷的途径来弄清这个URL支持哪些HTTP方法。从Flask0.6开始实现了自动处理。 |
6.静态文件
动态Web 应用也会需要静态文件,通常是CSS和JavaScript 文件。理想状态下,你已经配置好Web 服务器来提供静态文件,但是在开发中,Flask 也可以做到。只是在你的包中或者是模块的所在目录中创建一个名为static 的文件夹,在应用中使用“/static”即可访问。
给静态文件生成URL,使用特殊的“/static” 端点名:
url_for("static",filename="style.css")
这个文件应该存储在文件系统上的“static/style.css”。
7.模版
模版是一个包含响应文件的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模版,Flask 使用了一个名为 “Jinja2” 的强大模版引擎。
渲染模版
默认情况,Flask在程序文件夹中的templates 子文件夹中寻找模版。下面通过一个实例学习如何渲染模版。
示例:渲染模版
创建 04 文件夹,在该文件夹中创建templates 文件夹,然后创建2个文件夹,分别命名为index.html和user.html,最后在04文件夹下创建render.py文件,渲染这些模版。目录结构如下所示:
templates/index.html 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
templates/user.html 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello,{{username}}!</h1>
</body>
</html>
render.py 代码如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def hello_world():
return render_template("index.html")
@app.route("/user/<username>")
def show_user_profile(username):
# 显示该用户的用户信息
return render_template("user.html", name=username)
if __name__ == "__main__":
app.run(debug=True)
Flask 提供的 render_template() 函数把 “Jinja2” 模版引擎集成到了程序中。render_template() 函数的第一个参数是模板的文件名。随后的参数都是键值对,表示模版中变量对应的真实值。在这段代码中,第二个模板收到一个名为name的变量。“name = name” 是关键字参数,这类关键字参数很常见,但如果你不熟悉它们的话,可能会觉得迷惑且难难以理解。左边“name”表示参数名,就是模板中使用的占位符;右边的“name”是当前作用域中的变量,表示同名参数的值。
运行效果如下图所示:
变量
在模板中使用的“{{username}}” 结构表示一个变量,它是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。 “Jinja2”能识别所有类型的变量,甚至是一些复杂的类型,例如,列表、字典、和对象。在模板中使用变量的一些示例如下:
<p>从字典中取一个值:{{mydict["key"]}}.</p>
<p>从一个列表中取一个值:{{mylist[3]}}.</p>
<P>从一个列表中取一个带索引的值{{mylist[myintvar]}}.</P>
<p>从一个对象的方法中去一个值:{{myobj.somemethod()}}.</p>
可以使用过滤器修改变量,过滤器名添加在变量之后,中间使用竖线分隔。例如,下述模板以首字母大写的形式显示变量 name 的值:
Hello,{{name|capitalize}}
Jinja2 提供的部分常用过滤器如下表所示:
名称 | 说明 |
safe | 渲染值时不转义 |
capitalize | 把首字母转成大写,其他字母转成小写 |
lower | 把值转成小写的形式 |
upper | 把值转成大写的形式 |
title | 把值中的每个单词的首字母都换成大写 |
trim | 把值的收尾空格去掉 |
striptags | 渲染之前把值中的所有的HTML 标签都删掉 |
safe过滤器值得特别说明一下。默认情况下,出于安全考虑,Jinja2 会转义所有变量。如果个交量的值为“<hI>HeHo<hI>”
,Jimja2会将其渲染成“'<hl>Hello</hl>”
,浏览器能显示这个hI
元素,但不会进行解释。很多情况下需要显示变量中存储的HTML
代码,这时就可以使用safe 过滤器。
控件
Jinja2 提供了多种控制结构,可用来改变模版的渲染流程。接下来我们将使用简单的例子介绍其中最有用的控制结构。
下面这个例子展示了如何在模板中使用条件控制语句:
{% if user %}
Hello,{{user}}
{% else %}
Hello,Stranger
{% endif %}
另外一种常见需求是在模板中渲染一组元素。如下所示展示了如何使用for循环实现这一需求:
<ul>
{% for comment in comments %}
<li>
{ {comment} }
</li>
{% endfor %}
</ul>
Jinja2 还支持宏。宏类似于 Python 代码中的函数。例如:
{% macro render_comment(comment) %}
<li>
{ {comment} }
</li>
{% endmacro %}
<ul>
{% for comment in comments %}
<li>
{ {comment} }
</li>
{% endfor %}
</ul>
为了独立使用宏,我们可以将其保存在单独的文件中,然后在需要使用的模板中导入:
{% import "macros.html" as macros %}
<ul>
{% for comment in comments %}
<li>
{ {comment} }
</li>
{% endfor %}
</ul>
需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有的模板中,以避免重复:
{% include "common.html" %}
另一种重复使用代码的强大方式的模板继承,它类似于Python 代码中的类继承。首先,创建一个名为base.html 的基模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% block head %}
<title>{% block title %}{% endblock %} - My Application</title>
{% endblock %}
</head>
<body>
{% block boby %}
{% endblock %}
</body>
</html>
block 标签定义的元素在衍生模板中修改,在本例中,我们定义了名为head、title和body 的块。注意,title 包含在head 中,下面这个示例是基模版的衍生模版:
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super()}}
<style>
</style>
{% endblock %}
{% block boby %}
<h1>Hello,World!</h1>
{% endblock %}
extends
指令声明这个模板衍生自base.html
。在extends
指令之后,基模板中的3 个块被重新定义,模板引擎会将其插入适当的位置。注意新定义的head块,在基模板中其内容不是空的,所以使用super()
函数获取原来内容。
Flask Web框架的使用(合集),到此就结束了,感谢大家阅读,如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)