第5节、Flask表单

binscor
2019-08-19 / 0 评论 / 577 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年09月10日,已超过1168天没有更新,若内容或图片失效,请留言反馈。

一、原生表单

1. 添加模板文件login.html,内容如下:

<form method="post" action="{{ url_for('check') }}">
    用户名:<input name="username" type="text" />
    <input type="submit" value="立即登录" />
</form>

2. 视图函数,如下:

# 登录
@app.route('/login/')
def login():
    return render_template('login.html')
P
# 校验
@app.route('/check/', methods=['POST'])
def check():
    print(request.form.get('username'))
    return 'Hello %s !' % request.form['username']

3. 将登录页面和校验的路由合并,如下:

@app.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        return 'Hello %s !' % request.form['username']
一个路由处理时,表单的action属性不用书写,默认提交到当前路由。

二、flask-wtf处理表单

说明:flask-wtf是一个用于表单处理的扩展库,提供了CSRF、校验等功能,使用非常方便

附:flask-wtf教程

1.跨站请求伪造保护(csrf)

附:浅谈CSRF攻击方式

Flask-WTF 能保护所有表单免受跨站请求伪造(Cross-Site Request Forgery,CSRF)的攻击。恶意网站把请求发送到被攻击者已登录的其他网站时就会引发 CSRF 攻击。为了实现 CSRF 保护,Flask-WTF 需要程序设置一个密钥。Flask-WTF 使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪。

#视图中  设置 Flask-WTF
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'#字典可用来存储框架、扩展和程序本身的配置变量。
#为了增强安全性,密钥不应该直接写入代码,而要保存在环境变量中。

#模板中使用
 {{ form.hidden_tag() }} #或   {{ form.csrf_token }}

2.关闭csrf

@app.route('/form/',methods=['post','get'])
def newform():
    form = NameForm(csrf_enabled = False)

3.flask-wtf常见字段类型和验证器

常见字段类型

字段类型说明
StringField普通文本字段
SubmitField提交按钮
PasswordField密码文本字段
HiddenField隐藏文本字段
TextAreaField多行文本字段
DateField文本字段,datetime.date格式
DateTimeField文本字段,datetime.datedatime格式
IntegerField文本字段,值为整数
FloatField文本字段,值为小数
BooleanField复选框,值为True或False
RadioField单选框
SelectField下拉框
FileField文件上传

常见验证器类

验证器说明
DataRequired确保字段有值 必填项
Email邮箱地址 验证邮箱
IPAddressIP地址
Length规定字符长度 有min和max两个值进行限制。
NumberRange输入数值的范围
EqualTo验证两个字段的一致性
URL有效的URL
Regexp正则验证
info = TextAreaField('个人信息',render_kw={'style':'resize:none;'}) #render_kw 给当前的标签添加属性

表单类

每个 Web 表单都由一个继承自Form的类表示。这个类定义表单中的一组字段(表单的内容与类的字段是一一对应的),每个字段都用对象(表单中的对象)表示。字段对象可附属一个或多个验证函数。

4.定义表单类

# 导入表单基类
from flask_wtf import FlaskForm
# 导入字段类型
from wtforms import StringField, SubmitField
# 导入验证器类
from wtforms.validators import DataRequired #必填字段

# CSRF需要使用
app.config['SECRET_KEY'] = '123456'
 
# 定义表单类 
class NameForm(FlaskForm):
    #name 为表单的name名称
    name = StringField('用户名', validators=[DataRequired()])
    submit = SubmitField('提交')

5.添加视图函数:

@app.route('/')
def index():
    # 创建表单对象
    form = NameForm()
    # 分配到模板中进行渲染
    return render_template('form.html', form=form)

6.模板文件中渲染表单:

Form 类有一个 hidden_tag 方法, 它在一个隐藏的 DIV 标签中渲染任何隐藏的字段,包括 CSRF 字段:

{# 原生渲染 #}
<form>
    {# CSRF的隐藏字段 #}
    {{ form.hidden_tag() }} #或   {{ form.csrf_token }}

    {# name字段,可以指定id、class等属性,定制显示效果 style='color:red 设置文本颜色 #}
    {{ form.name.label() }}{{ form.name(id='xxx', class='yyy',style='color:red) }}
    {{ form.name.errors }} #错误提示
    {# submit字段 #}
    {{ form.submit() }}
</form>

7.在视图中使用bootstrap的wtf快速渲染表单

#使用bootstrap快速渲染  其它代码不变
from flask_bootstrap import Bootstrap
app.config['BOOTSTRAP_SERVE_LOCAL'] = True #加载本地的js文件
bootstrap = Bootstrap(app)

{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{{ wtf.quick_form(form) }}

模板中

更改表单提交地址和表单排列样式

wtf.quick_form(form,form_type='horizontal',action= url_for('login') )

查看都有哪些参数可以查看 wtf.html 里面的 quick_form 宏

{# bootstrap渲染 #}
{% extends 'bootstrap/base.html' %}

{# 导入渲染工具 #}
{% import 'bootstrap/wtf.html' as wtf %}

{# 渲染表单 调用宏方法 wtf.quick_form#}
{% block content %}
    <div class="container">{{ wtf.quick_form(form,action=url_for('upload')) }}</div>
{% endblock %}

8.表单校验

@app.route('/', methods=['GET', 'POST'])
def index():
    # return '表单使用'
    name = None
    # 创建表单对象
    form = NameForm()
    # 表单校验
    #validate_on_submit 会便捷地检查该请求是否是一个 POST 请求以及是否有效。
    if form.validate_on_submit(): 
        name = form.name.data
        form.name.data = ''
    # 分配到模板中进行渲染
    return render_template('form.html', form=form, name=name)

9.自定义表单验证器

自定义字段验证:就是写一个validate_字段名'的函数,如下:

# 定义表单类
class NameForm(FlaskForm):
    name = StringField('用户名', validators=[DataRequired()])
    submit = SubmitField('提交')

    #如果字段中也存在Length对象的验证  那么这俩个验证会重复叠加
    #userName = StringField('用户名',validators=[DataRequired(),Length(3, 6, message='请输入正确的长度')])
       
    # 自定义字段验证函数,格式是写一个'validate_字段名'的函数 
    def validate_name(self, field):
        if len(field.data) < 6:
            raise ValidationError('用户名长度不能少于6个字符')

10.所有的字段和验证器的使用

class Form(FlaskForm):
    hidde = HiddenField()
    username = StringField('用户名')
    userpass = PasswordField('密码')
    confirm = PasswordField('确认密码',validators=[EqualTo('userpass',message='密码和确认密码不一致')])
    info = TextAreaField('个人信息',render_kw={'style':'resize:none;'})
    birth = DateField('出生年月',format='%Y/%m/%d')
    birthday = DateTimeField('生日日期')
    age = IntegerField('age',validators=[NumberRange(min=6,max=99,message='年龄范围6~99')])
    money = FloatField('money')
    rember = BooleanField('记住我')
    sex = RadioField('sex',choices=[('m','男'),('w','女')])
    address = SelectField('address',choices=[('1001','北京'),('1002','上海'),('1003','深圳')])
    photo = FileField('photo')
    email = StringField('email',validators=[Email(message='请输入合法的邮箱地址')])
    ip = StringField('ip',validators=[IPAddress(message='输入合法的ipv4地址')])
    url = StringField('url',validators=[URL(message='请输入正确的url')])
    phone = StringField('手机号码',validators=[Regexp("[1][3-8][0-9]{9}$",flags=re.I|re.M|re.S,message='输入正确的手机号码')])
    # re.I 不区分大小写
    # re.S 使.匹配换行符
    # re.M 改变 ^ 和 $ 作用 使之可以多行匹配
    submit = SubmitField('submit')
    #自定义表单验证器 validate_ 死的 + 验证的属性名 当点击的时候 就会执行当前的自定义表单验证器
    def validate_username(self,field):
        if self.username.data == 'zhangsan':
            raise ValidationError('当前用户已存在')
0

评论 (0)

取消