模板代码的复用 ( 宏( Macro )、继承( Block )、包含( include ) 均能实现代码的复用 )
二、宏: 宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。
1 {% macro input(label='', type='text', value='', name='') %} 2 <label>{{ label }}</label><input type="{{ type }}" name="{{ name }}"><br/> 3 {% endmacro %} 4 5 6 <form> 7 {{ input('用户名:', name='username') }} 8 {{ input('密码:',type='password', name='password') }} 9 {{ input('确认密码:',type='password2', name='password2') }} 10 {{ input(type='submit', value='注册') }} 11 12 </form>
为了重复使用宏,可以将其保存在单独的文件中,然后在需要使用的模板中导入,再调用:
1 {% import 'macro.html' as func %} 2 3 <form> 4 {{ func.input('用户名:', name='username') }} 5 {{ func.input('密码:',type='password', name='password') }} 6 {{ func.input('确认密码:',type='password', name='password2') }} 7 {{ func.input(type='submit', value='注册') }} 8 9 </form>
二、继承: 继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。
首先,创建一个名为base.html 的基模板:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>Document</title> 6 </head> 7 <body> 8 {% block top %} 9 顶部内容 10 {% endblock top %} 11 12 {% block content %} 13 中间内容 14 {% endblock content %} 15 16 {% block bottom %} 17 底部内容 18 {% endblock bottom %} 19 </body> 20 </html>
下面是子模板:
1 {% extends 'base.html' %} 2 3 {% block content %} 4 {{ super() }} 5 需要填充的内容 6 {% endblock content %}
三、包含: 包含(include)是直接将目标模板文件整个渲染出来。
创建一个名为 include.html 的基模板,然后就可以在其它的文件中使用了:
1 {% include 'common.html' ignore missing %} 2 {# 如文件不存在,加上 ignore missing 关键字,程序就不会报异常 #}
模板中特有的变量和函数
config:{{ config.DEBUG }} 请求上下文中两个变量: 当前路由路由:{{ request.url }} session取值 {{ session.name }} 应用上下文中1个变量: g变量:{{ g.name }} 两个直接可以使用的函数: <a href="{{ url_for('index') }}">回到首页</a><br/> 获取闪现消息: {% for message in get_flashed_messages() %} {{ message }} {% endfor %
Flask-WFT表单
在Flask中,为了处理web表单,我们可以使用 Flask-WTF 扩展,它封装了 WTForms,并且它有验证表单数据的功能。
WTForms支持的HTML标准字段
字段对象 | 说明 |
---|---|
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密码文本字段 |
HiddenField | 隐藏文件字段 |
DateField | 文本字段,值为 datetime.date 文本格式 |
DateTimeField | 文本字段,值为 datetime.datetime 文本格式 |
IntegerField | 文本字段,值为整数 |
DecimalField | 文本字段,值为decimal.Decimal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True 和 False |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMutipleField | 下拉列表,可选择多个值 |
FileField | 文件上传字段 |
SubmitField | 表单提交按钮 |
FormField | 把表单作为字段嵌入另一个表单 |
FieldList | 一组指定类型的字段 |
WTForms常用验证函数
验证函数 | 说明 |
---|---|
DataRequired | 确保字段中有数据 |
EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
Length | 验证输入的字符串长度 |
NumberRange | 验证输入的值在数字范围内 |
URL | 验证URL |
AnyOf | 验证输入值在可选列表中 |
NoneOf | 验证输入值不在可选列表中 |
使用 Flask-WTF 实现表单
1、配置参数,关闭 CSRF 校验( 如不关闭需用到下面提到的CSRF解决 )
app.config['WTF_CSRF_ENABLED'] = False
2、使用 Flask-WTF 需要配置参数 SECRET_KEY。
(CSRF_ENABLED是为了CSRF(跨站请求伪造)保护。 SECRET_KEY用来生成加密令牌,当CSRF激活的时候,该设置会根据设置的密匙生成加密令牌。)
app.config['SECRET_KEY']='SECRET_KEY'
示例代码:
- 视图函数
1 from flask import Flask,render_template, flash 2 #导入wtf扩展的表单类 3 from flask_wtf import FlaskForm 4 #导入自定义表单需要的字段 5 from wtforms import SubmitField,StringField,PasswordField 6 #导入wtf扩展提供的表单验证器 7 from wtforms.validators import DataRequired,EqualTo 8 9 10 app = Flask(__name__) 11 app.config['SECRET_KEY']='SECRET_KEY' 12 13 #自定义表单类,文本字段、密码字段、提交按钮 14 class RegisterForm(FlaskForm): 15 username = StringField("用户名:", validators=[DataRequired("请输入用户名")], render_kw={"placeholder": "请输入用户名"}) 16 password = PasswordField("密码:", validators=[DataRequired("请输入密码")]) 17 password2 = PasswordField("确认密码:", validators=[DataRequired("请输入确认密码"), EqualTo("password", "两次密码不一致")]) 18 submit = SubmitField("注册") 19 20 #定义根路由视图函数,生成表单对象,获取表单数据,进行表单数据验证 21 @app.route('/demo2', methods=["get", "post"]) 22 def demo2(): 23 register_form = RegisterForm() 24 # 验证表单 25 if register_form.validate_on_submit(): 26 # 如果代码能走到这个地方,那么就代码表单中所有的数据都能验证成功 27 username = request.form.get("username") 28 password = request.form.get("password") 29 password2 = request.form.get("password2") 30 # 假装做注册操作 31 print(username, password, password2) 32 return "success" 33 else: 34 if request.method == "POST": 35 flash("参数有误或者不完整") 36 37 return render_template('temp_register.html', form=register_form) 38 39 if __name__ == '__main__': 40 app.run(debug=True)
- 模板页面
1 <form method="post"> 2 {{ form.username.label }} {{ form.username }}<br/> 3 {{ form.password.label }} {{ form.password }}<br/> 4 {{ form.password2.label }} {{ form.password2 }}<br/> 5 {{ form.submit }} 6 </form>
CSRF(跨站请求伪造)
- CSRF全拼为Cross Site Request Forgery,译为 跨站请求伪造。
- CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。
- 造成的问题:个人隐私泄露以及财产安全。
CSRF攻击图解:
在Flask中解决CSRF攻击
在 FlaskForm 中实现校验
1、设置应用程序的 secret_key (用于加密生成的 csrf_token 的值)
app.secret_key = "#此处可以写随机字符串#"
2、然后在模板表单里面的前面添加如下代码:
{{ xxx.csrf_token() }} {# xxx 为视图函数传入模板中的自定义表单类 #}
单独使用
1、设置应用程序的 secret_key (用于加密生成的 csrf_token 的值)
app.secret_key = "#此处可以写随机字符串#"
2、导入 flask_wtf.csrf 中的 CSRFProtect 类,进行初始化,并在初始化的时候关联 app
from flask.ext.wtf import CSRFProtect CSRFProtect(app)
注意:
- 如果模板中有表单,不需要做任何事。与之前一样:
<form method="post"> {{ form.csrf_token }} ...... </form>
- 但如果模板中没有表单,仍需要 CSRF 令牌:
<form method="post" action="/"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" /> </form>