资讯专栏INFORMATION COLUMN

使用Flask-WTF制作一个带验证码的登陆表单

i_garfileo / 789人阅读

摘要:目前还不是很熟悉的验证表单的原理,比如验证应该是用,这种就是放在后端处理的。此时就需要手动控制表单的生成。如果表单验证失败,失败的消息保存在中。

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") }}

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

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

如果表单验证错误,没有处理`form.errors`的话前端就不会有任何提示,给人造成的错觉就是`validate_on_submit`方法没有执行。

不要忘记form.hidden_tag()。这个是加载并隐藏csrf_token。没有csrf_token,一般会报错。

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

生成验证码

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

views.py中处理表单

处理表单的逻辑:

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

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

按条件返回模板

代码如下:

@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)

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

最终结果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37769.html

相关文章

  • Flask Web Development —— Web表单(上)

    摘要:每个表单域都可以连接到一个或多个是一个用于检查用户提交的输入是否合法的函数。表单域构造函数的第一个参数是一个,在渲染表单到时会使用。验证确保提交的表单域不为空。表单域验证都是直接从包中导入。表格展示了一组支持的标准表单域。 第二章中介绍的request对象公开了所有客户端发送的请求信息。特别是request.form可以访问POST请求提交的表单数据。 尽管Flask的request...

    CODING 评论0 收藏0
  • Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

    摘要:于是乎服务器向用户浏览器发送了一个名为的,它的值是的值。标记着该用户已经登陆了跳转到其他页面,告诉用户成功登陆了。注册多个用户,不断发帖子,扰乱正常发帖秩序。在处理表单的中刷新。监听用户提交事件。 什么是Session Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务器把用户的信息以某种...

    Java_oldboy 评论0 收藏0
  • Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

    摘要:于是乎服务器向用户浏览器发送了一个名为的,它的值是的值。标记着该用户已经登陆了跳转到其他页面,告诉用户成功登陆了。注册多个用户,不断发帖子,扰乱正常发帖秩序。在处理表单的中刷新。监听用户提交事件。 什么是Session Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务器把用户的信息以某种...

    fox_soyoung 评论0 收藏0
  • Python入门网络爬虫之精华版

    摘要:学习网络爬虫主要分个大的版块抓取,分析,存储另外,比较常用的爬虫框架,这里最后也详细介绍一下。网络爬虫要做的,简单来说,就是实现浏览器的功能。 Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scrapy,这里最后也详细介绍一下。 首先列举一下本人总结的相关文章,这些覆盖了入门网络爬虫需要的基本概念和技巧:宁哥的小站-网络爬虫,当我们在浏览器中输入...

    Bmob 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<