Flask基础
命令行启动
$ flask run --port=8080
运行过程
- 客户端向服务器发起请求
- 服务器把请求交给Flask实例
- Flask实例通过
Werkzeug
根据URL请求与视图函数之间的对应关系来进行路由分发 根据每个URL请求,找到具体的视图函数并进行调用
- Flask程序中路由一般是通过程序实例的装饰器实现
Flask调用视图函数后,可以返回2种内容:
- 字符串:将视图函数的返回值作为响应内容,返回给客户端
- HTML模板内容:获得数据后,将数据传入HTML模板中,模板引擎
Jinja2
负责渲染数据,然后返回响应数据给客户端
简单应用
- 新建一个Flask项目
- 导入Flask类
# 导入Flask
from flask import Flask
- 创建实例。需要传入一个参数
name
,指向程序所在的模块
app = Flask(__name__)
- 配置路由。通过装饰器将路由映射到视图函数
@app.route('/')
def index():
return 'Hello World!'
- 完整代码
# -*- coding:utf-8 -*-
# 导入Flask
from flask import Flask
# 创建实例
app = Flask(__name__)
# 路由与视图函数对应关系
@app.route('/')
def index():
return 'Hello World!'
# 启动程序
if __name__ == '__main__':
app.run()
路由
请求方式
- 使用
methods
参数指定可接受的请求方式,可指定多种,默认只接受GET
请求
@app.route('/', methods=['GET','POST'])
def hello():
return 'Hello'
参数处理
有时候需要将同一类URL映射到同一个视图函数处理,例如某个分类下不同的图书返回不同信息
- 使用
<>
定义路由动态参数 - 并且将该参数传入视图函数
- 使用
@app.route('/code/<book_id>')
def book(book_id):
print(type(book_id)) # 默认是str
return f'当前书本ID为: {book_id}'
有时候需要对路由做访问优化。例如上面的
book_id
应是int
类型- 只需要在
<>
中的变量名前加上指定类型:
即可 - 若指定为
int
类型,则访问/code/abc
等str
类型的路由时会返回404 Not Found
- 只需要在
@app.route('/code/<int:book_id>')
def book(book_id):
print(type(book_id)) # 此时为int
return f'当前书本ID为: {book_id}'
模板引擎
视图函数的作用有2个:处理业务逻辑和内容。
- 模板其实是一个包含响应文本的文件,用变量表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
- 使用真实值替换变量,再返回最终的字符串,这个过程称为渲染。Flask使用模板引擎
Jinja2
来渲染模板
返回HTML
前面都是写如何返回字符串,那么如果需要返回HTML模板,则可以通过
render_template
实现render_template()
函数中第一个参数是模板文件名,后面的参数都是键值对,表示模板中变量对应的真实值
# -*- coding:utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html') # templates目录下的index.html
if __name__ == '__main__':
app.run()
动态渲染
如果需要在模板中使用某些动态的参数,则需要在视图函数中传递参数
- 视图函数中通过
render_template()
函数传参 - HTML模板文件中通过
{{}}
使用该变量
- 视图函数中通过
@app.route('/')
def index():
url = "www.naraku.cn"
return render_template('index.html', url=url)
index.html
:
<h1>欢迎来到: {{ url }}</h1>
用法
- 注释:
{# #}
{# 这是注释 #}
{# {{name}} #}
- 控制:
{% %}
{% if id>50 %}
{{id}} => 大于50
{% elif id<50 %}
{{id}} => 小于50
{% else %}
{{id}} => 等于50
{% endif %}
{% for num in nums %}
<p>当前数字为: {{num}}</p>
{% endfor %}
- 举个例子
def index():
id = 100
nums = [1, 2, 3, 4, 5]
return render_template('index.html', id=id, nums=nums)
index.html
{% if id>50 %}
<h1>id为: {{id}} => 大于50</h1>
{% elif id<50 %}
<h1>id为: {{id}} => 小于50</h1>
{% else %}
<h1>id为: {{id}} => 等于50</h1>
{% endif %}
{# 注释: 上面是if,下面是for #}
{% for num in nums %}
<p>当前数字为: {{num}}</p>
{% endfor %}
过滤器
- 过滤器的本质是函数,有时候不仅仅只是需要输出变量的值,还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用Python中某些方法的,那么就用到了过滤器
使用方式:
- 过滤器的使用方式:
变量名 | 过滤器
{{ name | filter(*args) }}
- 如果没有任何参数传给过滤器,可以省略括号
{{ name | filter }}
- 举个例子
@app.route('/')
def index():
name = "naraku"
return render_template('index.html', name=name)
{# 字符串变大写 #}
<p>{{ name | upper }}</p>
链式调用
Jinja2
中,过滤器支持链式调用,从左到右按顺序执行
<p>{{ 'Hello World' | upper | reverse }}</p>
常用过滤器
format
:格式化输出
<p>{{ '%s' | format(name) }}</p>
safe
:禁用转义
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize
:首字母大写,其余小写
<p>{{ 'hello' | capitalize }}</p>
upper/lower
:全部转为大写或小写
<p>{{ 'Hello World' | lower }}</p>
<p>{{ 'Hello World' | upper }}</p>
reverse
:字符串反转
<p>{{ 'Hello World' | reverse }}</p>
truncate
:字符串截断
<p>{{ 'hello world' | truncate(3) }}</p>
striptags
:渲染前把所有HTML标签删除
<p>{{ '<em>hello</em>' | striptags }}</p>
Web表单
Web表单是Web程序的基本功能,它是HTML页面中负责数据采集的部件。表单中有三部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。
简单示例
视图函数
路由需要有
GET
和POST
请求,需要判断请求方式- 路由中添加参数
methods
,以列表的方式传入请求方式GET
和POST
- 引入
request
对象,获取请求方式及参数
- 路由中添加参数
@app.route("/", methods=['GET', 'POST'])
def index():
# 获取请求方式
if request.method == "POST":
# 获取请求参数