当前位置:   article > 正文

flask教程8:模板_flask 模板

flask 模板


一、模板与自定义过滤器

1 模板

      使用模块可以在templates新建一个html文件,如index.html文件,如基础模板分别为:
      程序基础模板:

index.html基础模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>name = {{name}}</p>
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

后端代码

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def index():
    data = {
        "name": "余登武",
    }
    return render_template("index.html", **data)


if __name__ == '__main__':
    app.run(debug=True, port=8000)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

      html文件中{{name}}表示的是一个变量,告诉模板引擎渲染时添加变量的值。 **data两个 **表示字符串变量。

      若传递的参数有列表或字典,仍可按照正常的取值方式,例如:字典.get,["关键词"];列表[索引]
      程序:

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def index():
    data = {
        "name": "python",
        "my_dict": {"itchat": "Beijing"},
        "my_list": [1, 2, 3, 4, 5],
        "my_int": 0
    }
    return render_template("index.html", **data)

if __name__ == '__main__':
    app.run(debug=True, port=8000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>name = {{name}}</p>
    <p>my_dict:itchat = {{my_dict["itchat"]}}</p>
    <p>my_dict:itchat = {{my_dict.get("itchat")}}</p>
    <p>my_list:my_int = {{my_list[my_int]}}</p>
    <p>my_list:my_int = {{my_list[1]}}</p>

</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2 过滤器

      flask有着自己的过滤器模块,如下展示:(即在变量后面加|过滤器名,连续过滤则|过滤器名|过滤器名
      格式{{变量|过滤器名}}
字符串过滤器`

  • safe:禁止转义
  • capitalize:把变量值的首字母转成大写,其余字母转小写
  • lower:把值转成小写
  • upper:把值转成大写
  • title:把值中的每个单词的首字母都转成大写
  • trim:把值的首尾空格去掉
  • reverse:字符串反转
  • format:格式化输出
  • striptags:渲染之前把值中所有的HTML标签都删掉

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>name = {{name}}</p>
    <p>my_dict:itchat = {{my_dict["itchat"]}}</p>
    <p>my_dict:itchat = {{my_dict.get("itchat")}}</p>
    <p>my_list:my_int = {{my_list[my_int]}}</p>
    <p>name = {{name | upper}}</p>
    <p>my_dict:itchat = {{my_dict.get("itchat") | lower | reverse}}</p>
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def index():
    data = {
        "name": "python",
        "my_dict": {"itchat": "Beijing"},
        "my_list": [1, 2, 3, 4, 5],
        "my_int": 0
    }
    return render_template("index.html", **data)


if __name__ == '__main__':
    app.run(debug=True, port=8000)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

转义过滤器讲解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post">
        <textarea name="text"></textarea>
        <input type="submit" value="提交">
    </form>
   输入文本是:{{text}}
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: yudengwu(余登武)
# @Date  : 2023/4/9
#@email:1344732766@qq.com
from flask import Flask, render_template,request
app = Flask(__name__)


@app.route("/",methods=["GET","POST"])
def index():
    text=""
    if request.method =="POST":
        text=request.form.get("text")
    return render_template("index.html", text=text)


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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
      查看源代码,发现已被转义(带html格式文本中代码被转义为纯文本)

      如果加入禁止转义

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post">
        <textarea name="text"></textarea>
        <input type="submit" value="提交">
    </form>
   输入文本是:{{text|safe}}
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

      结果为 <font color="red>123</font>代码被很好执行啦

3自定义过滤器

      若flask自带的过滤器模块满足不了要求,可以使用自定义的过滤器方法

  • 第一种方法,编写相关函数添加进过滤器模块中:
  • 第二种方法,使用装饰器的方法给过滤器模块添加新功能:

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/")
def index():
    data = {
        "name": "python",
        "my_dict": {"itchat": "Beijing"},
        "my_list": [1, 2, 3, 4, 5],
        "my_int": 0
    }
    return render_template("index.html", **data)


# 自定义过滤器
"""第一种方法"""

# 1.编写过滤器函数
def list_step_2(li):
    return li[::2]


# 注册过滤器
"""app.template_filter第一个参数为过滤器函数,过滤器函数名字"""
app.add_template_filter(list_step_2, "li2")


"""第二种方法 装饰器"""
@app.template_filter("li3")
def list_step_3(li):
    return li[::3]


if __name__ == '__main__':
    app.run(debug=True, port=8000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>name = {{name}}</p>
    <p>my_dict:itchat = {{my_dict["itchat"]}}</p>
    <p>my_dict:itchat = {{my_dict.get("itchat")}}</p>
    <p>my_list:my_int = {{my_list[my_int]}}</p>
    <p>name = {{name | upper}}</p>
    <p>my_dict:itchat = {{my_dict.get("itchat") | lower | reverse}}</p>
    <p>guolvqi = {{my_list | li2}}</p>
    <P>guolvqi2  = {{my_list | li3}}</P>
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

二、表单

1表单

    Web 表单是 Web 应用程序的基本功能,它是 HTML 页面中负责数据采集的部件。通常情况下,表单有三个 部分组成,分别是表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML 页面数据采集,通过表单 将用户输入的数据提交给服务器。 实际上,要让模板动态呈现表单数据,可使用 request.form 属性传递数据过来即可。

py文件

# 引入Flask
from flask import Flask, render_template, request
 
# 创建Flask实例
app = Flask(__name__)
app.debug = True
 
 
@app.route('/logintest/')
def login_test():
    return render_template("login_test.html")
 
 
@app.route('/handle/', methods=['POST'])
def handle():
    # form 表单信息
    form_results = request.form
    # 显示
    name = form_results.get('name')
    age = form_results.get('age')
    pro = form_results.get('pro')
    description = form_results.get('description')
    # 数据
    results = {
        '姓名': name,
        '年龄': age,
        '程序成绩': pro,
        '自我评价': description,
    }
    return render_template("results.html", results=results)
 
 
if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在 templates目录下创建对应的两个html文件:

login_test.html results.html

login_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录测试</title>
</head>
<body>
    <h1>表单显示</h1>
    {#  action="handle" 意思是从路由访问这个函数 #}
    {#  注意这个 /handle/ 要跟路由保持一致,斜杠也要对应上否则会出错  #}
    <form method="post" action="/handle/">
        <p>姓名:<input type="text" name="name" ></p>
        <p>年龄:<input type="number" name="age"></p>
        <p>编程成绩:<input type="number" name="pro"></p>
        <p>自我评价:<textarea name="description" ></textarea> </p>
        <p><input type="submit" value="提交"></p>
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

results.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>显示结果</title>
</head>
<body>
    <h1>结果</h1>
    <table border="1">
        {% for key,value in results.items() %}
            <tr>
                <td>{{ key }}</td>
                <td>{{ value }}</td>
            </tr>
        {% endfor %}
    </table>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

    上述代码无法进行表单验证(即验证有没有填写,填写是否正确等,如果需要验证,则需要在py文件里加入多个if语句(如判断是不是文字,是否填写))

2表单扩展

    下面通过 Flask-WTF 扩展库、使用 Flask-WTF 实现表单
在 Flask 框架中,为了快速处理 Web 表单,我们一般使用 Flask-WTF 库,它封装了 WTForms ,并且它有验证表单数据的功能。若要使用该库,则需要先进行安装 pip install Flask-WTF

    还需特别注意的是,使用 Flask-WTF 库时,必须要配置参数 SECRET_KEY 属性。当设定好了 SECRET_KEY 后,可用来生成加密令牌,当 CSRF 激活时,该设置会根据设置的密匙生成加密令牌。

*使用 Flask-WTF 实现表单

    对于 Flask-WTF 扩展库,可以定义模型,此时需要继承自 Form 基类,需从 flask.ext.wtf 中导入,且字段和验 证函数可以直接从 WTForms 包中导入。此处,因 Flask 与 werkzeug 的兼容性问题,因此要安装 werkzeug pip install werkzeug

py文件

# 引入Flask
from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired, EqualTo

# 创建Flask实例
app = Flask(__name__)
app.debug = True

# 密钥
app.config["SECRET_KEY"] = "123abchello"

#自定义表单类、文本字段、密码字段、提交按钮
class LoginForm(FlaskForm):
    # 用户名
    username = StringField(label=u'用户名', validators=[DataRequired()])
    # 密码
    password = PasswordField(label=u"密码", validators=[DataRequired()])
    # 确认密码
    repwd = PasswordField(label=u'确认密码', validators=[DataRequired(), EqualTo("password", "两次密码输入不一致")])
    # 提交
    submit = SubmitField(label=u"提交")


@app.route("/index/")
def index():
    post_form = LoginForm() #类对象
    return render_template("index.html", form=post_form) #form=post_form 把模板变量传过去


@app.route("/login/", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        post_form = LoginForm()#类对象  把用户填写的数据赛到这个对象来的
        if post_form.validate_on_submit(): #validate检验
            name = post_form.username.data
            password = post_form.password.data
            repwd = post_form.repwd.data
            print("姓名:", name)
            print("密码:", password)
            print("确认密码:", repwd)
            flash(f"欢迎{name}")
        else:
            flash("信息有误,请重新输入!")
        return render_template("results.html", form=post_form)


if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wtf_login</title>
</head>
<body>
    <h1>登录表单</h1>
    <form method="post" action="/login/">
        {{ form.csrf_token() }}
        <p><b>{{ form.username.label }}</b>{{ form.username }}</p>
        <p><b>{{ form.password.label }}</b>{{ form.password }}</p>
        <p><b>{{ form.repwd.label }}</b>{{ form.repwd }}</p>
        <p><b>{{ form.submit() }}</b></p>
        {% for msg in get_flashed_messages() %}
            {{ msg }}
        {% endfor %}
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

results.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>你好\(@^0^@)/你好</title>
</head>
<body>
    {% for msg in get_flashed_messages() %}
            <h1>{{ msg }}</h1>
    {% endfor %}
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
如果前后密码不一致

讲解
    闪现 :请求完成后给用户的提醒消息,flask的核心特性, flash函数实现效果

  • 视图函数中调用flash()方法
  • html中要使用get_flashed_messages()

        flask-wtf的表单验证方法form.validate_on_submit() 会对进行CSRF验证,如果form.csrf_token()代码写错相当于没有form.csrf_token()进行渲染该字段,那么flask-wtf在验证表单签名时就会一直不通过。

        CSRF攻击的大致方式如下:某用户登录了A网站,认证信息保存在cookie中。当用户访问攻击者创建的B网站时,攻击者通过在B网站发送一个伪造的请求提交到A网站服务器上,让A网站服务器误以为请求来自于自己的网站,于是执行相应的操作,该用户的信息便遭到了篡改。总结起来就是,攻击者利用用户在浏览器中保存的认证信息,向对应的站点发送伪造请求。在前面学习cookie时,我们介绍过用户认证通过保存在cookie中的数据实现。在发送请求时,只要浏览器中保存了对应的cookie,服务器端就会认为用户已经处于登录状态,而攻击者正是利用了这一机制。

三、创建表单模型类与模板使用

if 语句

{%if%} {%endif%} 
  • 1

for语句

{%for item in samples %} {% endfor %}
  • 1

3.1 表单模型类

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wtf_login</title>
</head>
<body>
    <h1>登录表单</h1>
    <form method="post" >
        {{ form.csrf_token() }}
        <p><b>{{ form.username.label }}</b>{{ form.username }}
        {% for msg in form.username.errors%}
            {{msg}}}
            {% endfor%}
        </p>
        <p><b>{{ form.password.label }}</b>{{ form.password }}
        {% for msg in form.password.errors%}
            {{msg}}}
            {% endfor%}
        </p>

        <p><b>{{ form.repwd.label }}</b>{{ form.repwd }}
        {% for msg in form.repwd.errors%}
            {{msg}}}
            {% endfor%}
        </p>

        <p><b>{{ form.submit() }}</b></p>
        {% for msg in get_flashed_messages() %}
            {{ msg }}
        {% endfor %}
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

py文件

# 引入Flask
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired, EqualTo

# 创建Flask实例
app = Flask(__name__)
app.debug = True

# 密钥
app.config["SECRET_KEY"] = "123abchello"

#自定义表单类、文本字段、密码字段、提交按钮
class LoginForm(FlaskForm):
    """
    自定义表单类
    label=u'标签', validators=验证器(列表格式)
    """

    # 用户名
    username = StringField(label=u'用户名', validators=[DataRequired()])
    # 密码
    password = PasswordField(label=u"密码", validators=[DataRequired()])
    # 确认密码
    repwd = PasswordField(label=u'确认密码', validators=[DataRequired(), EqualTo("password", "两次密码输入不一致")])
    # 提交
    submit = SubmitField(label=u"提交")


@app.route("/index/")
def index():
    post_form = LoginForm() #类对象
    return render_template("index.html", form=post_form) #form=post_form 把模板变量传过去


if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

结果

查看网页源代码
flask_wtf 已自动将表单类被渲染成html代码(前端语言)

四 、使用表单接受并检验参数

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wtf_login</title>
</head>
<body>
    <h1>登录表单</h1>
    <form method="post">
        {{ form.csrf_token() }}
        <p><b>{{ form.username.label }}</b>{{ form.username }}
        {% for msg in form.username.errors%}
            {{msg}}}
            {% endfor%}
        </p>
        <p><b>{{ form.password.label }}</b>{{ form.password }}
        {% for msg in form.password.errors%}
            {{msg}}}
            {% endfor%}
        </p>

        <p><b>{{ form.repwd.label }}</b>{{ form.repwd }}
        {% for msg in form.repwd.errors%}
            {{msg}}}
            {% endfor%}
        </p>

        <p><b>{{ form.submit() }}</b></p>
        {% for msg in get_flashed_messages() %}
            {{ msg }}
        {% endfor %}
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

py文件

# 引入Flask
from flask import Flask, session,render_template,redirect,url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired, EqualTo

# 创建Flask实例
app = Flask(__name__)
app.debug = True

# 密钥
app.config["SECRET_KEY"] = "123abchello"

#自定义表单类、文本字段、密码字段、提交按钮
class LoginForm(FlaskForm):
    """
    自定义表单类
    label=u'标签', validators=验证器(列表格式)
    """
    # 用户名
    username = StringField(label=u'用户名', validators=[DataRequired()])
    # 密码
    password = PasswordField(label=u"密码", validators=[DataRequired()])
    # 确认密码
    repwd = PasswordField(label=u'确认密码', validators=[DataRequired(), EqualTo("password", "两次密码输入不一致")])
    # 提交
    submit = SubmitField(label=u"提交")


@app.route("/register/",methods=["GET","POST"])
def register():
    post_form = LoginForm() #创建表单对象。如果是POST请求,前端发送了数据,flask会把数据在构造form对象时存放到对象中
    #post_form.validate_on_submit判断form中的数据是否合理以及csrf验证
    #如果验证成功,返回真,否则flase(验证失败和请求方式不是get)
    if post_form.validate_on_submit():
        #表示验证合格
        # 提取数据
        uname=post_form.username.data
        pwd=post_form.password.data
        pwd2=post_form.repwd.data
        print(uname,pwd,pwd2)
        #模拟登录
        session["username"]=uname
        return  redirect(url_for("index")) #定向到登录成功界面
    #如果失败
    return render_template("register.html", form=post_form) #form=post_form 把模板变量传过去


@app.route("/index/")
def index():
    user_name=session.get("urername","") #提取参数。默认空
    return "你好,主人"



if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

结果
登录界面

输入信息有错时

输入正确和cstf无误时

五、模板宏的使用

类似于python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余。

不带参数的宏
macro类似def

定义 
{% macro input()%}
<input type="text" name="name" value="" size="30">
{% endmacro%}
使用
{{input()}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

带参数宏

定义 带参数
{% macro input1(type,value,size)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
使用
{{input1(type="password",value="",size=50)}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

算例
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>定义不带参数宏</h1>
{% macro input()%}
<input type="text"  value="" size="30">
{% endmacro%}
{{input()}}
<hr/>

<h1>定义 带参数</h1>
{% macro input1(type,value,size)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
{{input1(type="password",value="",size=50)}}
<hr/>

<h1>定义 带参数(默认值)</h1>
{% macro input2(type="text",value="",size=50)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
{{input2(type="password",value="123")}}

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

py文件

# 引入Flask
from flask import Flask, render_template

# 创建Flask实例
app = Flask(__name__)
app.debug = True

@app.route("/index/")
def index():

    return render_template("index.html")



if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
网页源代码

六 、宏定义在外部的使用

在其它模板文件中先导入,再调用

示例
macro1.html
该html只要宏部分

{% macro input4(type="text",value="",size=50)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
  • 1
  • 2
  • 3

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>定义不带参数宏</h1>
{% macro input()%}
<input type="text"  value="" size="30">
{% endmacro%}
{{input()}}
<hr/>

<h1>定义 带参数</h1>
{% macro input1(type,value,size)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
{{input1(type="password",value="",size=50)}}
<hr/>

<h1>定义 带参数(默认值)</h1>
{% macro input2(type="text",value="",size=50)%}
<input type="{{type}}" value="{{value}}" size="{{size}}">
{% endmacro%}
{{input2(type="password",value="123")}}
<hr/>

<h1>外部宏</h1>
{% import "macro1.html" as m_input %}
{{m_input.input4()}}
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

核心代码

{% import "macro1.html" as m_input %}
{{m_input.input4()}}
  • 1
  • 2

py文件

# 引入Flask
from flask import Flask, render_template

# 创建Flask实例
app = Flask(__name__)
app.debug = True
@app.route("/index/")
def index():
    return render_template("index.html")
if __name__ == '__main__':
    # 在测试环境下开启服务
    app.run()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

七 :模板继承与包含

继承

先说模板的继承,定义一个父模板(命名为“father.html”),其格式为:

{% block 自定义名称 %}
{% endblock 自定义名称 %}
  • 1
  • 2

定义一个子模板(命名为“son.html”),其格式为:

{% extends "father.html" %}
{% block 自定义名称 %}
插入内容
{% endblock 自定义名称 %}

  • 1
  • 2
  • 3
  • 4
  • 5

下面举一个例子进行说明:
定义文件father.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>——————第一个按钮——————{% block top %}{% endblock top %}</h1>
    <h1>——————第二个按钮——————{% block hello %}{% endblock hello %}</h1>
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

定义文件son.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% extends "father.html" %}
    {% block top %}
        <br>
        <input name="第一" type="text" value=" " size="50">
    {% endblock top %}

    {% block hello %}
        <br>
        <input name="第二" type="password" value="" size="50">
    {% endblock hello %}
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

定义渲染的函数:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def top():
    return "这是主页"

@app.route("/hello")
def index():
    return render_template("son.html")

if __name__ == '__main__':
    app.run(debug = True, port = 8000)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

包含include

include语句:可以把一个模板引入到另外一个模板中
把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置

当定义了两个html文件时,通过include语句可以将这两个html内容加载到第三个html文件中。
{% include 'header.html' %}
        主体内容
{% include 'footer.html' %}
## 输出的结果按照指定的位置顺序依次在网页模板上显示。
  • 1
  • 2
  • 3
  • 4
  • 5

八 、闪现

在模板中获取闪现信息

Flask 提供了一个非常简单的方法来使用闪现系统向用户反馈信息。闪现系统使得在一个请求结束的时候记录一个信息,然后在且仅仅在下一个请求中访问这个数据,强调flask闪现是基于flask内置的session的,利用浏览器的session缓存闪现信息。所以必须设置secret_key

简单的在模板中实现获取闪现信息

实例:
server.py

from flask import Flask, flash, redirect, render_template, \
     request, url_for

app = Flask(__name__)
app.secret_key = 'some_secret'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != 'admin' or \
                request.form['password'] != '123':
            error = '登录失败'
        else:
            flash('恭喜您登录成功')
            return redirect(url_for('index'))
    return render_template('login.html', error=error)

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

注意:这个 flash() 就可以实现在下一次请求时候,将括号内的信息做一个缓存。不要忘记设置secret_key
index.html 模板:

{% with messages = get_flashed_messages() %}  # 获取所有的闪现信息返回一个列表
  {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

<h1>主页</h1>
  <p>跳转到登录页面<a href="{{ url_for('login') }}">登录?</a>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注意:{% with messages = get_flashed_messages() %} # 获取所有的闪现信息返回一个列表

这里是login.html 模板

<h1>登录页面</h1>
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
    <form action="" method=post>
    用户名:
    <input type=text name=username>
    密码:
    <input type=password name=password>
    <p><input type=submit value=Login></p>
</form>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/538467
推荐阅读
相关标签
  

闽ICP备14008679号