flask教程8:模板

news2024/11/16 21:45:06

文章目录

  • 一、模板与自定义过滤器
    • 1 模板
    • 2 过滤器
      • 转义过滤器讲解
    • 3自定义过滤器
  • 二、表单
    • 1表单
    • 2表单扩展
  • 三、创建表单模型类与模板使用
    • 3.1 表单模型类
  • 四 、使用表单接受并检验参数
  • 五、模板宏的使用
  • 六 、宏定义在外部的使用
  • 七 :模板继承与包含
    • 继承
    • 包含include
  • 八 、闪现
    • 在模板中获取闪现信息
    • 简单的在模板中实现获取闪现信息


一、模板与自定义过滤器

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>

后端代码

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)

      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)
<!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>

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>

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)

转义过滤器讲解

<!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>

#!/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)

      查看源代码,发现已被转义(带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>

      结果为 <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)

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表单

    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()

在 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>

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>

    上述代码无法进行表单验证(即验证有没有填写,填写是否正确等,如果需要验证,则需要在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()

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>

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>
如果前后密码不一致

讲解
    闪现 :请求完成后给用户的提醒消息,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%} 

for语句

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

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>

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()

结果

查看网页源代码
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>

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()

结果
登录界面

输入信息有错时

输入正确和cstf无误时

五、模板宏的使用

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

不带参数的宏
macro类似def

定义 
{% macro input()%}
<input type="text" name="name" value="" size="30">
{% endmacro%}
使用
{{input()}}

带参数宏

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

算例
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>

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()


网页源代码

六 、宏定义在外部的使用

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

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

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

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>

核心代码

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

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()

七 :模板继承与包含

继承

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

{% block 自定义名称 %}
{% endblock 自定义名称 %}

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

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

下面举一个例子进行说明:
定义文件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>

定义文件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>

定义渲染的函数:

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)

包含include

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

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

八 、闪现

在模板中获取闪现信息

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()

注意:这个 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>

注意:{% 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>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/503669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PVE 安装 windows10

pve 安装教程大家可以参考视频&#xff1a;pve 安装 pve 安装 Windows10 视频教程&#xff1a;pve 安装Windows10 在安装好 pve 后我们就可以进行虚拟机的安装了。当然我们可以自行决定是否有必要进行 win10 的安装。 准备工作 1. 下载 win10 镜像文件&#xff1a;https://…

数据结构与算法基础(王卓)(35):交换排序之快排【第二阶段:标准答案、初步发现问题】

目录 第二阶段&#xff1a;一分为二 整个快排算法的程序运行大框架&#xff1a; 做出的改动&#xff08;和原来程序的区别&#xff09;&#xff1a; Project 1: PPT标准答案&#xff1a; Project 1小问题&#xff1a; Project 1还存在着一个巨大的问题&#xff1a; 具体问…

嵌入式软考备考_8 软件测试

软件测试 测试&#xff1a;在规定的条件下操作程序&#xff0c;以发现错误&#xff0c;对软件质量进行评估。 对象&#xff1a;程序&#xff0c;数据&#xff0c;文档。 目的&#xff1a;发现错误&#xff0c;看是否满足用户需求&#xff0c;发现错误产生的原因&#xff08;…

汇编四、51单片机汇编指令2

1、机器码 (1)MOV A,#0x60对应机器码为7460 (2)7460对应二进制 0111 0100 0110 0000 0x74对应指令&#xff0c;0x60对应立即数。 (3)immediate data翻译为立即数。 (4)可人为查表把汇编转为机器码&#xff0c;也可通过编译器把汇编转为机器码。 2、汇编常见缩写 (1)Rn: n可…

leetcode-040-组合总和2

题目及测试 package pid040; /* 40. 组合总和 II 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 。注意&#xff1a;解集不能包含重复的组合…

Vue中使用EasyPlayer播放H265视频流

需求说明 需要在Vue2的项目中使用EasyPlayer进行H265视频流的播放。使用官方的最新版本加载H265会有问题。一直处于加载中… 实现步骤 引入easyplayer,这里最开始引入了最新版会有问题&#xff0c;因此引入的是3.3.12版本&#xff0c;可参照官方文档进行配置。 EasyPlayer示…

HBase整合Phoenix

HBase整合Phoenix 创建软件目录 mkdir -p /opt/soft cd /opt/soft下载软件 wget https://dlcdn.apache.org/phoenix/phoenix-5.1.3/phoenix-hbase-2.5-5.1.3-bin.tar.gz解压 hbase tar -zxvf phoenix-hbase-2.5-5.1.3-bin.tar.gz修改 hbase 目录名称 mv phoenix-hbase-2.5…

(初)进程概念

目录 认识冯诺依曼系统 操作系统(Operator System) 设计OS的目的&#xff1a; 定位&#xff1a; 如何理解管理&#xff1a; 总结&#xff1a; 系统调用和库函数概念&#xff1a; 进程 基本概念 &#xff1a; 描述进程PCB task_struct - PCB的一种 task_struct内容分…

编译安装最新的Linux系统内核

现在还有不少机器是CentOS8 Stream系统&#xff0c;虽然上了贼船&#xff0c;不影响用就是了。8的编译和7大同小异&#xff0c;只是踩了更多的坑在这里记录一下&#xff0c;或许会帮到看到的朋友。 安装编译环境 CentOS8安装必要的包 yum groupinstall "Development Too…

【P13】JMeter 常数吞吐量定时器(Constant Throughput Timer)

文章目录 1、基于计算吞吐量&#xff1a;只有此线程2、基于计算吞吐量&#xff1a;所有活动线程3、基于计算吞吐量&#xff1a;当前线程组中的所有活动线程4、基于计算吞吐量&#xff1a;所有活动线程&#xff08;共享&#xff09;5、基于计算吞吐量&#xff1a;当前线程组中的…

【2023/05/08】雅卡尔织布机

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第3天。 Share The world puts off its mask of vastness to its lover. It becomes small as one song,as one kiss of the eternal. 译文&#xff1a; 世界对着它的爱人&#xff0c;把它浩瀚的面具揭…

已做过算法题总结2

20. 有效的括号 (括号匹配是使用栈解决的经典问题&#xff0c;这道题主要是记住三种不成立的情况) 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串&#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用…

解密链表元素移除:三种巧妙思路,轻松驱逐难缠结点

本篇博客会讲解力扣“203. 移除链表元素”的解题思路&#xff0c;这是题目链接。 老规矩&#xff0c;先来审题&#xff1a; 以下是一些示例&#xff1a; 以下是提示&#xff1a; 本题的思路还挺多的&#xff0c;不过都是链表的常规操作。 思路1 万能的尾插法。遍历链表&am…

[Golang] 爬虫实战-用多层嵌套结构体去接收多层嵌套数据

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

量子计算(10)编程实践2:隐形传态算法

目录 一、算法目的 二、算法原理 三、pyqpanda实现代码 四、测试结果 一、算法目的 量子隐形传态&#xff0c;又称量子遥传、量子隐形传输、量子隐形传送、量子远距传输或量子远传&#xff0c;是一种利用分散量子缠结与一些物理讯息的转换来传送量子态至任意距离的位置的技…

AutoSar CAN网络管理(CanNm)

文章目录 网络管理目的主动唤醒和被动唤醒状态管理1. 总线睡眠模式&#xff08;Bus-Sleep Mode&#xff09;2. 准备总线睡眠模式&#xff08;Prepare Bus-Sleep Mode&#xff09;3. 网络模式&#xff08;Network Mode&#xff09;3.1 重复报文状态(RepeatMessageState)3.2 常规…

基于springboot+mysql+jpa+html实现商品销售信息系统

基于springbootmysqljpahtml实现商品销售信息系统 一、系统介绍1、系统主要功能&#xff1a;2.涉及技术框架&#xff1a;3.本项目所用环境&#xff1a; 二、功能展示三、其它系统四、获取源码 一、系统介绍 1、系统主要功能&#xff1a; 订单管理模块 商品管理模块 品牌管理模…

【项目实战】—— 我们应该如何正确得创建线程池?

项目实战-我们应该如何正确得创建线程池&#xff1f; 对于现在而言多线程编程已经成为程序员必备的职业技能了&#xff0c;在开发实践过程中&#xff0c;你是否也遇到过相关多线程问题&#xff0c;比如创建多少线程才是合适的&#xff1f;线程池该如何创建&#xff1f;今天我们…

类和对象中(2)

文章目录 一、运算符重载1、运算符重载出现的原因2、在全局和类里实现运算符重载3、赋值运算符重载1、为什么赋值运算符重载不能写在全局 &#xff1f;2、什么时候需要自己实现赋值运算符重载 &#xff1f; 4、前置和后置重载5、运算符重载的优势 二、const成员函数1、两个常见…

GNN与MLP:GNN是一种泛化器

图神经网络&#xff08;GNN&#xff09;作为图表示学习的模型&#xff0c;建立在MLP架构之上&#xff0c;具有额外的消息传递&#xff0c;以允许特征在节点之间流动。作者通过引入一个被称为P-MLP的中间模型&#xff0c;将GNN性能增益的主要来源定位为其内在的泛化能力&#xf…