表单处理Flask-WTF案例(二)之验证码登录

1. 验证码生成

2. 登录表单forms.py


class LoginForm(FlaskForm):
    name = StringField(
        # 指的是表单前面的内容;
        label="用户名",
        validators=[
            DataRequired("请输入用户名!"),
            Length(3, 20),
        ],
        render_kw={
            'placeholder': "请输入用户名",
            "class": "form-control"
        }

    )

    pwd = PasswordField(
        label="密码",
        validators=[
            DataRequired("请输入密码!")
        ],
        render_kw={
            'placeholder': "请输入密码",
            "class": "form-control"
        }

    )

    verify_code = StringField(

        label="验证码",

        validators=[
            DataRequired(),
        ]
    )

    submit = SubmitField(
        render_kw={
            'value': "登录",
            'class': 'btn btn-success pull-right'
        }

    )


3. 视图函数

  • 向html页面响应验证码图片


# 将验证码图片传给前端;
@app.route('/code/')
def get_code():
    # 1. 生成验证码;
    from doc.get_code import gene_code
    image, code = gene_code()

    # 2. 将验证码图片以二进制的方式写在内存中
    buf = BytesIO()
    image.save(buf, 'png')
    buf_str = buf.getvalue()
    # 3. 将数据响应给前端页面
    response = make_response(buf_str)
    response.headers['Content-Type'] = 'image/png'

    # 将验证码内容写入session会话中;
    session['code'] = code
    print(code)

    return response

  • 用户登录处理
@app.route('/login/', methods=['POST', 'GET'])
def login():
    # 实例化定义的登录表单;
    form = LoginForm()

    # 判断用户的HTTP请求方法
    if request.method == 'POST':
        # 1). 接收提交的数据;
        data = form.data
        name = data['name']
        pwd = data['pwd']
        code = data['verify_code']

        # 2). 判断用户名是否存在, 密码是否正确?
        u = User.query.filter_by(name=name).first()

        if u and check_password_hash(u.pwd, pwd):
            if code == session['code']:
                session['user'] = u.name
                session['user_id'] = u.id
                userlog = UserLog(
                    user_id=u.id,
                    ip=request.remote_addr,
                    area=get_ip_area(request.remote_addr)
                )
                db.session.add(userlog)
                db.session.commit()
                return '登录成功'
            else:
                flash("验证码错误", 'error')
                return redirect('/login/')
        else:
            # flash: 消息闪现,
            # 如何在前端html页面显示? Jinja2 get_flash_messages()
            # 返回的是一个列表, 想依次显示内容, 需要用到for循环;
            flash('用户或者密码不正确!')
            return redirect(url_for('login'))
    else:
        return render_template('login.html', form=form)
  • 用户登出

@app.route('/logout/')
def logout():
    # 将会话中的key值弹出;
    session.pop('user', None)
    session.pop('user_id', None)
    # 注销跳转到登录页面, 或者公共首页
    return redirect(url_for('login'))

3. 登录页面(templates/login.html)

{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as  wtf %}


{% block content %}
    <div class="col-md-8 col-md-offset-2">

        {#  显示闪现的所有信息   #}
        {% for msg in get_flashed_messages(category_filter='ok') %}
            <div class="alert alert-success alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <strong>Success!</strong> {{ msg }}.
            </div>
        {% endfor %}
        {% for msg in get_flashed_messages(category_filter='error') %}
            <div class="alert alert-warning alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <strong>Warning!</strong> {{ msg }}.
            </div>
        {% endfor %}

        {{ wtf.quick_form(form) }}
        <img src="/code/" onclick="this.src='/code/'">
    </div>
{% endblock %}

4. 效果展示

  • 获取验证码
    这里写图片描述
    这里写图片描述

  • 登录界面效果

这里写图片描述

这里写图片描述

5. 源代码下载

源代码下载

猜你喜欢

转载自blog.csdn.net/gf_lvah/article/details/81145557
今日推荐