flask 引入 flask-wtf 做安全表单

环境:

  python 3.7.4

  win 10

 

模块:

  flask 1.1.2

  Flask-WTF 0.14.3

 

资料文档:

  官网:https://flask-wtf.readthedocs.io/en/stable/

  辅助网站:http://wtforms.simplecodes.com/docs/0.6.1/fields.html

  中文官网:http://www.pythondoc.com/flask-wtf/

 

目录结构:

  

 

 

flask 引入 flask-wtf 做安全表单

  创建表单类: 以下是FormClass
from flask_wtf import FlaskForm,RecaptchaField
from wtforms import StringField, TextAreaField, SubmitField, SelectField, PasswordField,DecimalField,FileField
from wtforms.validators import DataRequired, EqualTo, Length, IPAddress


"""
官网:https://flask-wtf.readthedocs.io/en/stable/
辅助网站:http://wtforms.simplecodes.com/docs/0.6.1/fields.html
中文官网:http://www.pythondoc.com/flask-wtf/

#字段
StringField             字符串
IntegerField            整型
TextAreaField           文本
PasswordField           密码
HiddenField             隐藏域
DateField               Datatime.data格式 年月日
DateTimeField           Datatime.datatime 格式 年月日 时分秒
FloatField              小数
RadioField              单选
SelectField             下拉
FileField               文件
SubmitField             提交

#表单常用的校验
Email                   邮件校验
EqualTo                 比较两个字段的值,常用于密码比较
IPAdress                格式的IP地址
length                  长度
NumberRange             数字范围
DataRequired            空值检查
Url                     验证是否符合url格式
AnyOf                   确保输入值在指定范围
NoneOf                  确保输入的值不在范围
"""


class Register(FlaskForm):
    username = StringField(
        label='username',
        validators=[DataRequired(message='username不可以为空')],
        render_kw={'placeholder': 'username', 'class': 'input_text'})
    password = PasswordField(
        label='password',
        validators=[DataRequired(message='password不可以为空'), Length(3, 8, '密码长度必须在3-8之间')])
    cpassword = PasswordField(
        label='cpassword',
        validators=[DataRequired(message='cpassword不可以为空'), EqualTo('password', '两次密码不一致')])
    title = StringField(
        label='新闻标题', validators=[DataRequired(message="请输入标题")], description="请输入标题",
        render_kw={"required": "required"})
    types = SelectField(
        label='新闻类型',
        choices=[('首页', '首页'), ('动漫周边', '动漫周边'), ('军事要闻', '军事要闻'), ('每日上海', '每日上海'), ('图片', '图片')])
    photo = FileField() # 文件上传

    submit = SubmitField('提交')

 

在视图中实例化 表单类 并返回给前端页面 渲染
from App.Login import login
from flask import render_template, request,flash
from .FormClass import Register
from werkzeug.utils import secure_filename


@login.route("/", methods=['GET', 'POST'])
def loginIndex():
    form = Register()
    if request.method == 'POST':
        # 验证表单
        if form.validate_on_submit():

            # 获取表单方式1
            username = form.username.data
            password = form.password.data
            print(username)
            print(password)

            # 获取表单方式2
            print(type(form.data))
            print(form.data)

            filename = secure_filename(form.photo.data.filename)
            form.photo.data.save('uploads/' + filename)

            return "success"
        else:
            # 验证失败
            print(form.errors)
            error_msg = form.errors
            error = ''
            for k, v in error_msg.items():
                print(k, v[0])
                error = v[0]
            flash(error)
    return render_template('login.html', form=form)

 

前端页面 引入传递过来的 表单类,渲染表单
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <form action="/" method="post" novalidate enctype="multipart/form-data">
        {% for message in get_flashed_messages() %}
            <div style="color: red">
                {{ message }}
            </div>
        {% endfor %}
        <div>{{ form.username.label }}</div>        <div>{{ form.csrf_token }}</div>

        <div>{{ form.username }}</div>
        <div>{{ form.password.label }}</div>
        <div>{{ form.password }}</div>
        <div>{{ form.cpassword.label }}</div>
        <div>{{ form.cpassword }}</div>
        <div>{{ form.title.label }}</div>
        <div>{{ form.title }}</div>
        <div><label for="types">类型</label>{{ form.types }}</div>
        <div>{{ form.photo }}</div>
        <div><input type="submit" value="提交"></div>
    </form>
</div>
</body>
</html>

PS:

  novalidate  这个表单参数 标识禁止浏览器对字段进行验证

  enctype="multipart/form-data"  这个表单参数 标识上传文件参数

  upload 文件夹为 上传后保存文件的目录

 

未探索完整的,其中有包括验证码的功能 未实现

链接 http://www.pythondoc.com/flask-wtf/form.html#module-flask_wtf.recaptcha

 

CSRF 通过Ajax 的方式 未实现

链接 http://www.pythondoc.com/flask-wtf/csrf.html#id1

 

posted @ 2021-01-04 00:26  Anec  阅读(174)  评论(0编辑  收藏  举报