返回介绍

用户注册

发布于 2025-01-02 21:53:50 字数 4652 浏览 0 评论 0 收藏 0

本章要构建的最后一项功能是注册表单,以便用户可以通过 Web 表单进行注册。 让我们在 app/forms.py 中创建 Web 表单类来开始吧:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from app.models import User

# ...

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Register')

    def validate_username(self, username):
        user = User.query.filter_by(username=username.data).first()
        if user is not None:
            raise ValidationError('Please use a different username.')

    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError('Please use a different email address.')

代码中与验证相关的几处相当有趣。首先,对于 email 字段,我在 DataRequired 之后添加了第二个验证器,名为 Email 。 这个来自 WTForms 的另一个验证器将确保用户在此字段中键入的内容与电子邮件地址的结构相匹配。

由于这是一个注册表单,习惯上要求用户输入密码两次,以减少输入错误的风险。 出于这个原因,我提供了 passwordpassword2 字段。 第二个 password 字段使用另一个名为 EqualTo 的验证器,它将确保其值与第一个 password 字段的值相同。

我还为这个类添加了两个方法,名为 validate_username()validate_email() 。 当添加任何匹配模式 validate_ <field_name> 的方法时,WTForms 将这些方法作为自定义验证器,并在已设置验证器之后调用它们。 本处,我想确保用户输入的 username 和 email 不会与数据库中已存在的数据冲突,所以这两个方法执行数据库查询,并期望结果集为空。 否则,则通过 ValidationError 触发验证错误。 异常中作为参数的消息将会在对应字段旁边显示,以供用户查看。

我需要一个 HTML 模板以便在网页上显示这个表单,我其存储在 app/templates/register.html 文件中。 这个模板的构造与登录表单类似:

{% extends "base.html" %}

{% block content %}
    <h1>Register</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.email.label }}<br>
            {{ form.email(size=64) }}<br>
            {% for error in form.email.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password2.label }}<br>
            {{ form.password2(size=32) }}<br>
            {% for error in form.password2.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

登录表单模板需要在其表单之下添加一个链接来将未注册的用户引导到注册页面:

    <p>New User? <a href="{{ url_for('register') }}">Click to Register!</a></p>

最后,我来实现处理用户注册的视图函数,存储在 app/routes.py 中,代码如下:

from app import db
from app.forms import RegistrationForm

# ...

@app.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)

这个视图函数的逻辑也是一目了然,我首先确保调用这个路由的用户没有登录。表单的处理方式和登录的方式一样。在 if validate_on_submit() 条件块下,完成的逻辑如下:使用获取自表单的 username、email 和 password 创建一个新用户,将其写入数据库,然后重定向到登录页面以便用户登录。

精雕细琢之后,用户已经能够在此应用上注册帐户,并进行登录和注销。 请确保你尝试了我在注册表单中添加的所有验证功能,以便更好地了解其工作原理。 我将在未来的章节中再次更新用户认证子系统,以增加额外的功能,比如允许用户在忘记密码的情况下重置密码。 不过对于目前的应用来讲,这已经无碍于继续构建了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文