使用Flask-WTF制作一个带验证码的登陆表单
admin
2023-07-31 01:43:54
0

Flask-WTF遇到的坑

在使用Flask-WTF的时候,使用qucik_form()快速生成表单的确是很爽,但是生成的表单的样式并不是想要的,这个时候就不能使用qucik_form()了。

PS:目前还不是很熟悉Flask-WTF的验证表单的原理,比如Require()验证应该是用JS,EqualTo这种就是放在后端处理的。有时间了需要好好读一读官方文档。

froms.py中定义了如下的Register表单:

class RegisterForm(Form):
    \"\"\"注册表单\"\"\"

    username = StringField(u\'昵称\', validators=[Required()])
    email = StringField(u\'邮箱\', validators=[Required(), Email()])
    password = PasswordField(u\'密码\', validators=[Required(), Length(6, 12, message=u\'密码长度在6到12为\')])
    password1 = PasswordField(u\'确认密码\', validators=[Required(), Length(6, 12, message=u\'密码长度在6到12为\'), EqualTo(\'password\', message=u\'密码必须一致\')])
    verification_code = StringField(u\'验证码\', validators=[Required(), Length(4, 4, message=u\'填写4位验证码\')])
    submit = SubmitField(u\'注册\')

verification_code字段中,需要加载验证码图片,此时在模板中使用qucik_form()就很难处理了。

此时就需要手动控制表单的生成。

自定义生成表单

在模板中,手动渲染很麻烦:

    
{{ form.hidden_tag() }}
{{ form.username.label(class=\"control-label\") | safe }} {{ form.username(class=\"form-control\", required=True) }}
{{ form.email.label(class=\"control-label\") | safe }} {{ form.email(class=\"form-control\", required=True) }}
{% if form.errors.password %}
{{ form.password.label(class=\"control-label\") | safe }} {{ form.password(class=\"form-control\", required=True) }} {% for error in form.errors.password %}

{{ error }}

{% endfor %}
{% else %}
{{ form.password.label(class=\"control-label\") | safe }} {{ form.password(class=\"form-control\", required=True) }}
{% endif %} {% if form.errors.password1 %}
{{ form.password1.label(class=\"control-label\") | safe }} {{ form.password1(class=\"form-control\", required=True) }} {% for error in form.errors.password1 %}

{{ error }}

{% endfor %}
{% else %}
{{ form.password1.label(class=\"control-label\") | safe }} {{ form.password1(class=\"form-control\", required=True) }}
{% endif %} {% if form.errors.verification_code %}
{{ form.verification_code.label(class=\"control-label\") | safe }} {{ form.verification_code(class=\"form-control\", required=True) }} {% for error in form.errors.verification_code %}

{{ error }}

{% endfor %}
{% else %}
{{ form.verification_code.label(class=\"control-label\") | safe }} {{ form.verification_code(class=\"form-control\", required=True) }}
{% endif %} {{ form.submit(class=\"btn btn-info submit\") }}

下面是在编写以上代码时遇到的坑:

  1. 在模板中需要处理form.errors。如果表单验证失败,失败的消息保存在form.errors中。

    如果表单验证错误,没有处理`form.errors`的话前端就不会有任何提示,给人造成的错觉就是`validate_on_submit`方法没有执行。
  2. 不要忘记form.hidden_tag()。这个是加载并隐藏csrf_token。没有csrf_token,一般会报错。

没有银弹
上面的代码只实现了非空验证、密码是否相等验证、密码长度验证等功能,不知道不用Flask-WTF改用HTML + JS实现是不是代码量差不多。

生成验证码

生成验证码使用PIL来生成图片。廖雪峰有介绍如何生成验证码图片PIL-廖雪峰

views.py中处理表单

处理表单的逻辑:

  1. 每次有请求后,就调用generate_verification_code()返回一个验证码图片的url和验证码文本,然后将验证码保存在session中。

  2. 每次验证表单后,验证表单中输入的验证码时候和session中的一致

  3. 按条件返回模板

代码如下:

@user.route(\'/register\', methods=[\'GET\', \'POST\'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        username = form.username.data
        print username
        if get_user(username):
            print \'账号已被注册\'
            flash(u\'账号已被注册\')
            code_img, code_text = generate_verification_code()
            session[\'code_text\'] = code_text
            return render_template(\'user/register.html\', form=form, code_img=code_img)
        if \'code_text\' in session and session[\'code_text\'] != form.verification_code.data:
            code_img, code_text = generate_verification_code()
            session[\'code_text\'] = code_text
            return render_template(\'user/register.html\', form=form, code_img=code_img)
        email = form.email.data
        password = form.password.data
        user = User(username=username, password=password, email=email)
        try:
            db.session.add(user)
            db.session.commit()
            return redirect(url_for(\'.index\'))
        except:
            print traceback.print_exc()
            db.session.rollback()
            flash(u\'注册失败\')
            code_img, code_text = generate_verification_code()
            session[\'code_text\'] = code_text
            return render_template(\'user/register.html\', form=form, code_img=code_img)
    code_img, code_text = generate_verification_code()
    session[\'code_text\'] = code_text
    return render_template(\'user/register.html\', form=form, code_img=code_img)

将验证码保存在图片中不是一个号办法,目前也没有想到如何保存。

最终结果

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...