Flask表单
6.4 表单
使用Flask-WTF表单扩展,可以帮助进行CSRF验证,帮助我们快速定义表单模板,而且可以帮助我们在视图中验证表的数据
pip install Flask-WTF
6.4.1 不使用Flask-WTF扩展时,表单需要自己处理
#模板文件 <form method='post'> <input type="text" name="username" placeholder='Username'> <input type="password" name="password" placeholder='password'> <input type="submit"> </form>
from flask import Flask,render_template,request @app.route('/login',methods=['GET','POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] print username,password return “success” else: return render_template(“login.html”)
6.4.2 使用Flask-WTF扩展
需要设置 SECRET_KEY 的配置参数,前端设置csrf_token
模板页:
<form method="post">
# 设置csrd_token {{ form.csrf_token }} {{ form.user_name.label }} <p>{{form.user_name}}</p> {% for msg in form.user_name.errors %} <p>{{msg}}</p> {% endfor %} {{ form.password.label }} <p>{{form.password}}</p> {% for msg in form.password.errors %} <p>{{msg}}</p> {% endfor %} {{ form.password2.label }} <p>{{form.password2}}</p> {% for msg in form.password2.errors %} <p>{{msg}}</p> {% endfor %} {{form.submit}} </form>
视图函数
# coding:utf-8 from flask import Flask, render_template, redirect, url_for, session from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, EqualTo app = Flask(__name__) app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f" # 定义表单的模型类 class RegisterForm(FlaskForm): """自定义的注册表单模型类""" # 名字 验证器/验证器 # DataRequired 保证数据必须填写,并且不能为空 user_name = StringField(label=u"用户名", validators=[DataRequired(u"用户名不能为空")]) password = PasswordField(label=u"密码", validators=[DataRequired(u"密码不能为空")]) password2 = PasswordField(label=u"确认密码", validators=[DataRequired(u"确认密码不能为空"), EqualTo("password", u"两次密码不一致")]) submit = SubmitField(label=u"提交")
@app.route("/register", methods=["GET", "POST"]) def register(): # 创建表单对象, 如果是post请求,前端发送了数据,flask会把数据在构造form对象的时候,存放到对象中 form = RegisterForm() # 判断form中的数据是否合理 # 如果form中的数据完全满足所有的验证器,则返回真,否则返回假 if form.validate_on_submit(): # 表示验证合格 # 提取数据 uname = form.user_name.data pwd = form.password.data pwd2 = form.password2.data print(uname, pwd, pwd2) session["user_name"] = uname return redirect(url_for("index")) return render_template("register.html", form=form)
6.5.1 if语句
{% if %} {% endif %}
6.5.2 for语句
{% for item in samples %} {% endfor %}
6.6.1 不带参数宏的定义与使用
定义:
{% macro input() %}
<input type="text"
name="username"
value=""
size="30"/>
{% endmacro %}
使用
{{ input() }}
6.6.2 带参数宏的定义与使用
定义
{% macro input(name,value='',type='text',size=20) %}
<input type="{{ type }}"
name="{{ name }}"
value="{{ value }}"
size="{{ size }}"/>
{% endmacro %}
使用
{{ input(value='name',type='password',size=40)}}
6.6.3 将宏单独封装在html文件中
文件名可以自定义macro.html
{% macro input() %}
<input type="text" name="username" placeholde="Username">
<input type="password" name="password" placeholde="Password">
<input type="submit">
{% endmacro %}
在其它模板文件中先导入,再调用
{% import 'macro.html' as func %}
{% func.input() %}
6.4 模板继承
父模板:base.html
{% block top %}
顶部菜单
{% endblock top %}
{% block content %}
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}
子模板:
{% extends 'base.html' %}
{% block content %}
需要填充的内容
{% endblock content %}
模板继承使用时注意点:
- 不支持多继承。
- 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。
- 不能在一个模板文件中定义多个相同名字的block标签。
- 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。
6.5 模板包含
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。它的功能是将另一个模板整个加载到当前模板中,并直接渲染。
示例:
include的使用
{\% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上ignore missing关键字。如果包含的模板文件不存在,会忽略这条include语句。
示例:
include的使用加上关键字ignore missing
{\% include 'hello.html' ignore missing %}
- 宏、继承、包含:
- 宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。
- 继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。
- 宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。
- 包含(include)是直接将目标模板文件整个渲染出来。
6.6 flask在模板中使用特殊变量和方法
6.6.1 config
config 对象就是Flask的config对象,也就是 app.config 对象。
{{ config.SQLALCHEMY_DATABASE_URI }}
6.6.2 request
就是 Flask 中表示当前请求的 request 对象,request对象中保存了一次HTTP请求的一切信息。
6.6.3 url_for
request常用的属性如下:
| 属性 | 说明 | 类型 |
|---|---|---|
| data | 记录请求的数据,并转换为字符串 | * |
| form | 记录请求中的表单数据 | MultiDict |
| args | 记录请求中的查询参数 | MultiDict |
| cookies | 记录请求中的cookie信息 | Dict |
| headers | 记录请求中的报文头 | EnvironHeaders |
| method | 记录请求使用的HTTP方法 | GET/POST |
| url | 记录请求的URL地址 | string |
| files | 记录请求上传的文件 | * |
{{ request.url }}
6.6.3 url_for
url_for() 会返回传入的路由函数对应的URL,所谓路由函数就是被 app.route() 路由装饰器装饰的函数。如果我们定义的路由函数是带有参数的,则可以将这些参数作为命名参数传入。
{{ url_for('index') }}
{{ url_for('post', post_id=1024) }}
6.6.4 get_messages (闪现)
get_flashed_messages方法:
返回之前在Flask中通过 flash() 传入的信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出。
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
from flask import Flask, render_template, flash app.config["SECRET_KEY"] = "SDHFOSDF" @app.route("/") def index(): if flag: # 添加闪现信息 flash("hello1") flash("hello2") flash("hello3") global flag flag = False return render_template("index.html")
<h1>闪现</h1> {% for msg in get_flashed_messages() %} <p>{{msg}}</p> {% endfor %}

浙公网安备 33010602011771号