Flask—表单、模板的宏、模板的继承与包含、模板中的一些特殊变量与方法、闪现

表单: 使用 Flask_WTF 表单扩展,可以 帮助进行CSRF验证,帮助我们快速定义表单模板,而且可以帮助我们在视图函数中验证表单的数据。前端进行了数据校验,在后端中也需要进行数据校验, 有了Flask_WTF就可以省去自己写if else判断了

WTForms 支持的HTML标准字段如下表:
字段类型 说明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密码文本字段
HiddenField 隐藏文本字段
DateField 文本字段,值为datetime.date 格式
DateTimeField 文本字段,值为datetime.datetime 格式
IntegerField 文本字段,值为整数
DecimalField 文本字段,值为decimal.Decimal
FloatField 文本字段,值为浮点数
BooleanField 复选框,值为True 和False
RadioField 一组单选框
SelectField 下拉列表
SelectMultipleField 下拉列表,可选择多个值
FileField 文件上传字段
SubmitField 表单提交按钮
FormField 把表单作为字段嵌入另一个表单
FieldList 一组指定类型的字段

WTForms验证函数如下表:
Email 验证电子邮件地址
EqualTo 比较两个字段的值;常用于要求输入两次密码进行确认的情况
IPAddress 验证IPv4 网络地址
Length 验证输入字符串的长度
NumberRange 验证输入的值在数字范围内
Optional 无输入值时跳过其他验证函数
Required 确保字段中有数据
Regexp 使用正则表达式验证输入值
URL 验证URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值不在可选值列表中

模板的宏:(详见macro.html)
定义:

{% macro input() %}
    <input type="text" value="" size=30>
{% end macro %}

使用:

{{ input() }}

从外部导入:

{% import "xx.html" as func_name %}

使用: {{ func_name.函数名() }}

模板的继承与包含:
继承:extends 导入继承的模板,操作对应的块block
包含:include 它的功能是将另一个模板整个加载到当前模板中,并直接渲染,比如:
{% include "hello.html" %} 如果包含的模板不存在,程序将会抛出异常,可以
加上ignore missing关键字,如果包含的模板不存在则忽略这条include语句,如:

{% include "hello.html" ignore missing %}

小结:
宏、继承、包含的功能都是为了实现代码的复用
继承(block)的本质是代码的替换,一般用来实现多个页面中重复不变的区域
宏(macro)的功能类似函数,可以传参,需要定义、调用
包含(include)是直接将目录模板文件直接渲染出来

一些特殊的变量和方法
在Flask中,有一些特殊变量和方法模板文件中直接访问。
1、config对象
config对象就是Flask的config对象,也是app.config对象
使用:{{ config.SECRET_KEY }}
2、request对象
request中保存了一次http请求中一切信息,它的属性之前已经介绍过了
使用:{{ request.url }}
3、url_for方法
url_for()会返回传入路由函数对应的url,如果定义的函数是带有参数的,则可以将这些参数作为命名参数传入
使用:{{ url_for("index") }} {{ url_for("post", username="xx") }}
4、get_flashed_messages()
返回之前Flask中通过flash(xxx)传入的信息列表
使用:

{% for msg in get_flashed_messages() %}
    <p>{{ msg }}</p>
{% endfor %}
from flask import Flask, render_template, redirect, url_for, session, Response
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, FileField
from wtforms.validators import DataRequired, EqualTo
from flask_wtf.file import FileRequired, FileAllowed
from flask import flash

app = Flask(__name__)


app.config["SECRET_KEY"] = "asdfghjkqwert"

flag = True

# 定义表单模型类
class RegisterForm(FlaskForm):
    # StringField(label=xxx, validators=[xxx]),label:说明标签;validators:检验器/验证器
    # DataRequired(”不合法的提示信息“):表示数据必须填写,且不能为空
    username = StringField(label="姓名", validators=[DataRequired("用户名不能为空!")])
    password = PasswordField(label="密码", validators=[DataRequired("密码不能为空!")])
    password2 = PasswordField(label="确认密码", validators=[DataRequired("确认密码不能为空!"), EqualTo("password", "两次密码不一致")])
    img = FileField(label="上传头像(jpg,png格式)", validators=[FileRequired(), FileAllowed(["jpg", "png"], "仅图片")])
    submit = SubmitField(label="提交")

@app.route("/register", methods=["GET", "POST"])
def register():
    # 创建表单对象,如果是post请求,前端发送了数据,Flask会把数据在构造form对象的时候,存放到对象中
    form = RegisterForm()
    # 判断form中的数据是否合理,如果满足所有验证器,则返回True
    # GET请求也能调用这个方法,不过GET请求中,form对象中数据为空,validate_on_submit直接返回False
    print(form.validate_on_submit())
    if form.validate_on_submit():
        # 验证合格,提取数据。注意:form.username是一个对象,form.username.data才可以获取数据
        username = form.username.data
        password = form.password.data
        password2 = form.password2.data
        img = form.img.data

        filename = img.filename
        print(filename)
        img.save(f"./static/{filename}")
        # 设置session
        session["username"] = username
        print(username, password, password2)
        # 重定向到index页面,进行反向解析,url中带参数需要按照视图函数的参数名传入
        return redirect(url_for("index", pic_name=filename))
        # return redirect(url_for("index"))
    return render_template("register.html", form=form)


# 在url中传递username参数
# @app.route("/index/<username>")
# def index(username):
#     print("Index Page")
#     return f"Hello {username}"


# 使用session获取username参数
@app.route("/index/<pic_name>")
def index(pic_name):
    print("Index Page")
    # with open("./xx.jpg", "rb") as f:
    #     content = f.name
    #     res = Response(content, mimetype="image/jpeg")
    # # return res 返回图片
    # 获取sess值
    username = session.get("username", "")
    return render_template("test_index.html", username=username, img_name=pic_name)


@app.route("/")
def shanxian():
    # 添加闪现信息,在这里存一次,模板文件渲染一次,请求完了之后会清除,即第二次请求时不在显示
    # flash保存数据虽然没有通过render_template传到模板,但是保存到了session中,所以需要设置"SECRET_KEY"
    global flag
    if flag:
        flash(1)
        flash("hello 2")
        flash("hello 3")
        flash("hello 4")
        flag = False  # flag 设置为False,第二次访问的时候不会在执行if判断
    return render_template("macro.html")


if __name__ == '__main__':
    app.run()
# register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
    <form method="post" enctype="multipart/form-data">
        {{ form.csrf_token }}

        {{ form.username.label }}
        <p>{{ form.username }}</p>
        {# 校验出错是,显示错误信息,这个errors就是定义字段时的提示信息 #}
        {% for msg in form.username.errors %}
            <p>{{ msg }}</p>
        {% endfor %}

        {{ form.password.label }}
        <p>{{ form.password }}</p>
        {# 校验出错是,显示错误信息,这个errors就是定义字段时的提示信息 #}
        {% for msg in form.password.errors %}
            <p>{{ msg }}</p>
        {% endfor %}

        {{ form.password2.label }}
        <p>{{ form.password2 }}</p>
        {# 校验出错是,显示错误信息,这个errors就是定义字段时的提示信息 #}
        {% for msg in form.password2.errors %}
            <p>{{ msg }}</p>
        {% endfor %}

        {{ form.img.label }}
        {{ form.img }}<br>
        {% for msg in form.img.errors %}
            <p>{{ msg }}</p>
        {% endfor %}


        {{ form.submit }}
    </form>
</body>
</html>
# macro.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

{# include 包含 base.html 模板文件,直接渲染出来 #}
{% include "base.html" ignore missing %}

<body>
    {# flask中一些特殊变量或方法的使用 #}
    <h1>flask中一些特殊变量或方法的使用</h1>
    <p>config对象:{{ config.SECRET_KEY }}</p>
    <p>request对象:{{ request.url }}</p>
    <p>url_for方法的使用:<a href="{{ url_for("index", pic_name="me.jpg") }}">index</a></p>
    <hr/>

    {# 模板宏的使用 #}
    {% macro input_1() %}
        <input type="text" value="" size="30">
    {% endmacro %}
    <h1>input_1 不带参数的使用</h1>
    {{ input_1() }}

    <hr/>

    {# 模板宏带参数,跟定义函数一样,这些参数也可以设置为默认值 #}
    {% macro input_2(type, value, size) %}
        <input type="{{ type }}" value="{{ value }}" size="{{ size }}">
    {% endmacro %}
    <h1>input_2 带参数使用</h1>
    {{ input_2("password", "", 40) }}

    <hr/>

    {# 模板宏带参数,设置默认值 #}
    {% macro input_3(type="text", value="", size=30) %}
        <input type="{{ type }}" value="{{ value }}" size="{{ size }}">
    {% endmacro %}
    <h1>input_3 带默认参数使用</h1>
    {{ input_3(type="password", size=40) }}

    <hr/>

    {# 模板宏定义在外部,使用 #}
    <h1>input_4 从外部“macro_input.html”导入使用</h1>
    {% import "macro_input.html" as m_input %}
    {{ m_input.input_4() }}

    <hr/>

    {# 闪现信息 #}
    <h1>闪现信息</h1>
    {% for msg in get_flashed_messages() %}
        <p>{{ msg }}</p>
    {% endfor %}

</body>
</html>
# macro_input.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>macro_input</title>
</head>
<body>
    {# 模板宏 定义 #}
    {% macro input_4() %}
        <input type="text" value="" size="30">
    {% endmacro %}
</body>
</html>
# test_index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
    Hello, {{ username }}<br>
    头像: <br><img src="../static/{{ img_name }}" width="200" height="260">
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值