Flask基础

命令行启动

$ flask run --port=8080

运行过程

  1. 客户端向服务器发起请求
  2. 服务器把请求交给Flask实例
  3. Flask实例通过Werkzeug根据URL请求与视图函数之间的对应关系来进行路由分发
  4. 根据每个URL请求,找到具体的视图函数并进行调用

    • Flask程序中路由一般是通过程序实例的装饰器实现
  5. 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/abcstr类型的路由时会返回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页面数据采集,通过表单将用户输入的数据提交给服务器。

简单示例

视图函数

  • 路由需要有GETPOST请求,需要判断请求方式

    • 路由中添加参数methods,以列表的方式传入请求方式GETPOST
    • 引入request对象,获取请求方式及参数
@app.route("/", methods=['GET', 'POST'])
def index():
    # 获取请求方式
    if request.method == "POST":
        # 获取请求参数