Flask进阶


Flask进阶

创建flask_demo15_cookie.py

"""
cookie

- 解释:用来保持服务器和浏览器交互的状态的,由服务器设置,存储在浏览器
- 作用:用来做广告推送
- cookie的设置和获取
    - 设置cookie:response.set_cookie(key, value, max_age)
        - max_age: 表示cookie在浏览器的存储时间,单位:秒
    - 获取cookie:request.cookies.get("key") 
"""


from flask import Flask, make_response, request

app = Flask(__name__)


# 设置cookie
@app.route("/set_cookie")
def set_cookie():
    # 调用 make_response() 方法获取响应体对象
    response = make_response()

    # 设置 cookie
    response.set_cookie("computer", "lenovo")

    # 设置 cookie 20秒后过期
    response.set_cookie("age", "23", 20)

    return response


# 设置cookie
@app.route("/get_cookie")
def get_cookie():
    # 获取 cookie
    name = request.cookies.get("computer")
    age = request.cookies.get("age")
    # 返回
    return f"name is {name}, age is {age}"


@app.route("/")
def helloworld():
    return "hello world Flask"


if __name__ == "__main__":
    app.run(debug=True)

2.session

创建flask_demo16_session.py

"""
session

- 解释:服务器和用户来做状态保持的,里面存储的是敏感信息(比如身份证、登录信息),由服务器设置,并存储在服务器
- 作用:用来做用户的登录状态保持
- session的设置和获取
    - 设置 session: session[key] = value
    - 获取 session: value = session.get(key)

- 注意:
    - session的存储依赖于 cookie
    - 存储在 cookie 中的 sessionID需要加密,需要设置 SECRET_KEY
"""
from flask import Flask, session

app = Flask(__name__)

# 设置 SECRET_KEY
app.config["SECRET_KEY"] = "DSFALSDJEsdlj32s"


# 设置 session
@app.route("/set_session/<path:name>")
def set_session(name):
    session["name"] = name
    return "set session"


# 获取 session
@app.route("/get_session")
def get_session():
    name = session.get("name")
    return f"set session, name is {name}"


@app.route("/")
def helloworld():
    return "hello world Flask"


if __name__ == "__main__":
    app.run(debug=True)

3.上下文

创建flask_demo17_content.py

"""
上下文【了解】
- 解释:就是一个容器
- 请求上下文
    - request: 封装的是请求相关的数据
    - session: 封装的是和用户相关的敏感信息
- 应用上下文【在项目中具体应用】
    - current_app: 是app的一个代理对象,可以通过他获取app身上设置的各种属性,主要用在模块化开发中
    - g: 一个局部的全局变量,主要用在装饰器中
"""

from flask import Flask, current_app

app = Flask(__name__)


@app.route("/")
def helloworld():
    print(app.config.get("DEBUG"))
    print(current_app.config.get("DEBUG"))
    return "hello world Flask"


if __name__ == "__main__":
    app.run(debug=True)

4.render_template

创建flask_demo18_render_template.py

"""
render_template【掌握】
- 解释:属于jinjia2的模板函数
- 好处:
    - 1. 以后的视图函数,只负责业务逻辑的处理,比如:数据库的增删改查
    - 2. 以后数据的展示,全部都由jinjia2的模板负责
- 使用格式:
    - response = render_template('模板文件')
"""
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    response = render_template("Ademo01.html")
    return response


if __name__ == "__main__":
    app.run(debug=True)

创建templates目录,在该目录下创建Ademo01.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ademo01</title>
</head>

<body>
    <h1>欢迎!</h1>
    <h2>各种变量的值</h2>
    <ul>
        <li>
            整数:{{number}}
        </li>
        <li>
            字符串:{{str}}
        </li>
        <li>
            元组:{{tuple}}
            <br>
            元组元素:{{tuple.0}}、{{tuple[1]}}、{{tuple.2}}、{{tuple[3]}}、{{tuple.4}}
        </li>
        <li>
            列表:{{list}}
            <br>
            列表元素:{{list.0}}、{{list[1]}}、{{list.2}}、{{list[3]}}、{{list.4}}
        </li>
        <li>
            字典:{{dict}}
            <br>
            <!-- 字典用 [] 取值时,内部参数须是字符串类型 -->
            字典元素:{{dict.name}}、{{dict["age"]}}
        </li>
    </ul>
</body>

</html>

variable

创建flask_demo19_variable.py

"""
模板语法:获取变量【理解】
- 解释:在模板中获取视图函数的变量
- 格式:
    - {{ 变量 }}


"""
"""
render_template【掌握】
- 解释:属于jinjia2的模板函数
- 好处:
    - 1. 以后的视图函数,只负责业务逻辑的处理,比如:数据库的增删改查
    - 2. 以后数据的展示,全部都由jinjia2的模板负责
- 使用格式:
    - response = render_template('模板文件')


注意:如果发现程序端口被占用
- 1. lsof -i:5000
- 2. kill [端口号]
"""
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    # 1. 定义各种类型的变量
    number = 10
    str = "木婉清"
    tuple = (1, 2, 3, 4, 5)
    list = [6, 7, 8, 9, 10]
    dict = {"name": "木婉清", "age": 23}
    # 2. 携带变量到模板中展示
    return render_template(
        "Ademo01.html", number=number, str=str, tuple=tuple, list=list, dict=dict
    )


if __name__ == "__main__":
    app.run(debug=True)

other_program

创建flask_demo20_other_program.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    # 1. 定义各种类型的变量
    number = 10
    str = "木婉清"
    tuple = (1, 2, 3, 4, 5)
    list = [6, 7, 8, 9, 10]
    dict = {"name": "木婉清", "age": 23}
    # 2. 携带变量到模板中展示
    return render_template(
        "Ademo02_other_program.html",
        number=number,
        str=str,
        tuple=tuple,
        list=list,
        dict=dict,
    )


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo02_other_program.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ademo01</title>
</head>

<body>
    <h1>欢迎!</h1>
    <h2>遍历元组中的偶数</h2>
    {% for i in tuple %}
    {% if i %2 == 0 %}
    {{i}}
    {% endif %}
    {% endfor %}

    <h2>遍历字典</h2>
    {%for k, v in dict.items()%}
    {{k}}:{{v}}
    {%endfor%}
</body>

</html>

string_filter

创建flask_demo21_string_filter.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    return render_template("Ademo03_stringFilter.html")


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo03_stringFilter.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>string-filter</title>
</head>

<body>

    safe: 禁止转义,让标签生效
    <!-- 没加safe,输出<em>hello</em> -->
    <p>{{'<em>hello</em>'}}</p>
    <!-- 加了safe,输出斜体的hello -->
    <p>{{'<em>hello</em>'|safe}}</p>

    capitalize: 把变量值的首字母转成大写,其余字母转小写
    <p>{{'hello world'|capitalize}}</p>

    lower: 把值转成小写
    <p>{{'HELLO'|lower}}</p>

    upper: 把值转成大写
    <p>{{'hello'|upper}}</p>

    title: 把值中的每个单词的首字母都转成大写
    <p>{{'hello world'|title}}</p>

    reverse: 字符串反转
    <p>{{'olleh'|reverse}}</p>

    format: 格式化输出
    <p>{{'%s is %d'|format('name', 17)}}</p>

    striptags: 渲染之前把值中的所有的HTML标签都删掉
    <p>{{'<em>hello</em>'|striptags}}</p>

</body>

</html>

list_filter

创建flask_demo22_list_filter.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    return render_template("Ademo04_listFilter.html")


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo04_listFilter.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>listFilter</title>
</head>

<body>
    <h1>列表过滤器</h1>
    first: 取第一个元素
    <p>{{[1, 2, 3, 4, 5, 6]|first}}</p>

    last: 取最后一个元素
    <p>{{[1, 2, 3, 4, 5, 6]|last}}</p>

    length: 获取列表长度
    <p>{{[1, 2, 3, 4, 5, 6]|length}}</p>

    sum: 列表求和
    <p>{{[1, 2, 3, 4]|sum}}</p>

    sort: 列表排序默认升序
    <p>{{[6, 5, 4, 3, 2, 1]|sort}}</p>

    过滤器的链式调用
    <p>{{'hello'| upper | reverse}}</p>
</body>

</html>

custom_filter

创建flask_demo23_custom_filter.py

"""
自定义过滤器【掌握】

- 解释:当系统提供的过滤器满足不了需求的时候,需要自定义
- 自定义过滤器有两种格式:
    - 1. 先定义好函数,再将函数添加到系统默认的过滤器列表中
        - def 函数名(): pass
        - app.add_template_filter(函数名, '过滤器名字')

    - 2. 定义函数的时候,直接使用系统过滤器进行装饰
        @app.template_filter('过滤器名字')
        def 函数名():
            pass

- 案例:
    - 1. 获取列表偶数和
    - 2. 翻转列表
"""
from flask import Flask, render_template

app = Flask(__name__)


# 1. 先定义好函数,再将函数添加到系统默认的过滤器列表中
def get_evenNumber(list):  # 获取偶数和
    sum = 0
    for i in list:
        if i % 2 == 0:
            sum += i
    return sum


# 参数1:关联的函数的名字;参数2:在模板中使用的过滤器的名字
app.add_template_filter(get_evenNumber, "evenNumber")


# 2. 定义函数的时候,直接使用系统过滤器进行装饰
@app.template_filter("list_reverse")
def list_reverse(list):  # 列表反转
    list.reverse()  # 直接返回的结果是 None
    return list


@app.route("/")
def helloworld():
    return render_template("Ademo05_custom_filter.html")


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo05_custom_filter.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>custom_filter</title>
</head>

<body>
    <h2>原列表:{{[1, 2, 3, 4, 5, 6]}}</h2>
    <h2>偶数列表:{{[1, 2, 3, 4, 5, 6] | evenNumber}}</h2>
    <h2>原列表:{{[1, 2, 3, 4, 5, 6]}}</h2>
    <h2>反转列表:{{[1, 2, 3, 4, 5, 6] | list_reverse}}</h2>
</body>
</html>

macro

创建flask_demo24_macro.py

"""
代码复用——宏【了解】

解释:相当于 python 中的函数,定义好一段功能,在需要的时候进行调用
"""
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    response = render_template("Ademo06_macro.html")
    return response


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo06_macro.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>macro</title>
</head>

<body>
    <!-- 定义宏 -->
    {% macro my_macro(name, password)%}
    用户名<input type="text" value="{{name}}"><br>
    密码<input type="password" value="{{password}}"><br>
    {% endmacro %}

    <!-- 调用当前文件宏 -->
    {{ my_macro("木婉清", '123456') }}

    <!-- 调用其他文件的宏 -->
    {% import 'Ademo07_other_macro.html' as other %}
    {{ other.my_input() }}
    {{ other.my_div() }}
</body>

</html>

创建templates/Ademo07_other_macro.html

<!-- 定义宏 -->
{% macro my_macro(name, password)%}
用户名:<input type="text" value="{{name}}"><br>
密码:<input type="password" value="{{password}}"><br>
{% endmacro %}

{% macro my_input()%}
输入框:<input type="text" value="{{name}}"><br>
{% endmacro %}

{% macro my_div()%}
<div>div</div>
{% endmacro %}

extends

创建flask_demo25_extends.py

"""
代码复用——继承

- 解释:一个子模版继承自父模板
- 作用:共性抽取,代码复用

- 父模板:
    - 所有子类都具有的相同的内容,在父模板中直接写死
    - 每个子类的模板中不一样的内容,使用block模板定义好

- 子模板:
    - 根据子类自己的需求,去重写父类中的block对应的内容
    - 如果重写之后,还想保留父类的内容,那么使用{{super()}}
    - 继承格式:{% extends '父文件名' %},写在页面的顶部

- 注意点:
    定义block的格式
    {% block 名称 %}
    {% endblock %}
"""
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    response = render_template("Ademo08_extends_son.html")
    return response


@app.route("/index")
def index():
    response = render_template("Ademo09_extends_son2.html")
    return response


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo08_extends_son.html

{% extends 'Ademo10_extends_base.html' %}

{% block contentBlock %}
<p>
    床前明月光<br>
    疑是地上霜<br>
    举头望明月<br>
    低头思故乡<br>
</p>
{% endblock %}

{% block footBlock %}
<div>
    <a href="/index">点我有惊喜!</a>
</div>
{% endblock %}

创建templates/Ademo09_extends_son2.html

{% extends 'Ademo10_extends_base.html' %}

{% block contentBlock %}
<p>
    床前明月光<br>
    李白睡的香<br>
    梦见牛魔王<br>
    吓得尿裤裆<br>
</p>
{% endblock %}

{% block footBlock %}
<div>
    <a href="/">点我有惊喜!</a>
</div>
{% endblock %}

创建templates/Ademo10_extends_base.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>extends</title>
</head>

<body>
    <!-- 头部部分 -->
    {% block titleBlock %}
    <h1>静夜思</h1>
    {% endblock %}

    <!-- 正文部分 -->
    {% block contentBlock %}

    {% endblock %}

    <!-- 底部部分 -->
    {% block footBlock %}
    <div>
        <a href="#">点我有惊喜!</a>
    </div>
    {% endblock %}
</body>

</html>

include

创建flask_demo26_include.py

"""
包含
"""
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def helloworld():
    response = render_template("Ademo11_include.html")
    return response


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo11_include.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>include</title>
</head>

<body>
    <!-- ignore missing保证不存在该html页面也不会报错 -->
    {%include 'Ademo03_stringFilter.html' ignore missing%}
</body>

</html>

practice

创建flask_demo27_practice.py

from flask import Flask, render_template

app = Flask(__name__)

my_list = [
    {"id": 1, "value": "我爱工作"},
    {"id": 2, "value": "工作使人快乐"},
    {"id": 3, "value": "沉迷于工作无法自拔"},
    {"id": 4, "value": "日渐消瘦"},
    {"id": 5, "value": "以梦为马,越骑越慢"},
]


@app.route("/")
def helloworld():
    response = render_template("Ademo12_practice.html", my_list=my_list)
    return response


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo12_practice.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>practice</title>
</head>

<body>
    <ul>
        <!-- 在 for 中使用 if -->
        {%for dict in my_list if dict.id != 5 %}

        {% if loop.index == 1 %}
        <li style="background: yellow;">{{dict.value}}</li>
        {% elif loop.index == 2 %}
        <li style="background: green;">{{dict.value}}</li>
        {% elif loop.index == 3 %}
        <li style="background: red;">{{dict.value}}</li>
        {% else %}
        <li style="background: purple;">{{dict.value}}</li>
        {% endif %}
        <!-- 从0开始的索引 -->
        <!-- <h3>{{loop.index0}}</h3> -->
        <!-- 从1开始的索引 -->
        <!-- <h3>{{loop.index}}</h3> -->
        {%endfor%}
    </ul>

</body>

</html>

flash

创建flask_demo28_flash.py

from flask import Flask, render_template, flash

app = Flask(__name__)
app.config["SECRET_KEY"] = "sadljf"


@app.route("/")
def helloworld():
    # 存储消息
    flash("登录成功")
    response = render_template("Ademo13_flash.html")
    return response


@app.route("/error")
def error():
    # 存储消息
    flash("登录失败")

    return "error"


if __name__ == "__main__":
    app.run(debug=True)

创建templates/Ademo13_flash.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flush</title>
</head>

<body>
    {{get_flashed_messages()}}
</body>

</html>