FlaskForm 验证码:检查用户是否已经存在

Has*_*med 1 python flask flask-sqlalchemy flask-wtforms

因此,当我谈到在注册帐户时检查用户名或电子邮件是否已被使用时,我正在关注 Corey Schafer 的 Flask 教程。我一生都无法理解这段代码是如何工作的,我想这是因为我是 Python 和 Flask 的新手,但它仍然不应该如此令人困惑。

class RegistrationForm(FlaskForm):

    username = StringField('Username', validators=[DataRequired(), Length(min=4,                                  
    max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    password_confirm = PasswordField('Confirm password', validators=[DataRequired(),EqualTo('password')])             
    submit = SubmitField('Sign Up')


def validate_username(self, username):
    user = User.query.filter_by(username=username.data).first()
    if user:
        raise ValidationError('That username is taken. Please choose 
        another.')

def validate_email(self, email):
    user = User.query.filter_by(email=email.data).first()
    if user:
        raise ValidationError('That email is taken. Please choose another.')
Run Code Online (Sandbox Code Playgroud)

那么,我不明白的具体部分是RegistrationForm类中的两个函数:首先,这两个函数如何知道用户名和电子邮件是什么?例如,如果我将函数定义中的“用户名”和“电子邮件”参数更改为“u_n”和“e_mail”之类的内容,然后使用“u_n.data”和“e_mail.data”运行查询,则代码仍然有效. 其次,如果我要将函数重命名为其他任何内容,代码将停止工作,我不明白为什么?

我知道这个问题的答案不能太复杂,但这让我非常恼火。任何帮助将不胜感激。

Nat*_*han 9

我将彻底解释这一点,所以请耐心等待,因为我将在最后回答您的具体问题,以确保您完全了解所有部分是如何协同工作的。

您的表单定义由以下代码块给出:

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)])                           
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    password_confirm = PasswordField('Confirm password', validators=[DataRequired(),EqualTo('password')])
    submit = SubmitField('Sign Up')
Run Code Online (Sandbox Code Playgroud)

这就是在屏幕上创建表单 UI以及用户在注册时最终看到的内容的原因。此表单创建是通过flask_wtf库完成的,并在 .html 的帮助下呈现在 html 页面中Jinja2Jinja2是一个模板引擎,Python 可以利用它来为具有动态数据的服务器端页面提供服务。现在这个表单定义中的变量是什么意思?[用户名,电子邮件,密码,confirm_password,提交] 好吧,这些是对表单字段的引用。例如,当用户输入他们的信息在您的网站上注册一个帐户时,他们使用的用户名是通过引用form.username.data场地。同样,要得到他们使用的密码,以注册,你必须引用form.password.data场等等等等...验证功能:validate_username(...)validate_email(..)你在你创建类的方法RegistrationForm(FlaskForm)类验证的唯一用户的emailusername当他/她通过单击Sign Up按钮提交其帐户详细信息时。如果其他用户已经在使用此用户名或电子邮件,则会抛出错误那么这是如何实现的呢?验证由models.py文件中创建的模型定义协助

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
    password = db.Column(db.String(60), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}', '{self.image_file}')"
Run Code Online (Sandbox Code Playgroud)

这些模型利用flask-sqlalchemy一个包装器在您的表中sqlalchemy进行查询,在本例中是您的user表。Sqlalchemy是一个Python SQL 工具包和 ORM,可以轻松提交 SQL 查询以及将对象映射到表定义,反之亦然。所以user = User.query.filter_by(username=username.data).first()正在利用你的User模型定义,它已经创建了flask-sqlalchemy,查询您的user表格,看看是否有人使用该用户名登录。该from flaskblog.models import User是它允许您使用import语句User模型来查询您user从您的表单定义文件中的表格。此外,我们可以使用username.data而不是必须使用的原因form.username.data因为这是您的对象方法,RegistrationForm所以我们可以直接访问用户名和电子邮件表单字段。

现在回答您的问题:

  1. “为什么如果我将函数定义中的 'username' 和 'email' 参数更改为类似 'u_n' 和 'e_mail' 并使用 'u_n.data' 和 'e_mail.data' 运行查询,代码是否仍然有效”

:这些只是函数参数变量,可以根据您认为合适的方式命名,因为您通过函数声明将用户名(或电子邮件)表单字段直接传递到函数中。IEvalidate_<field_name>

  1. “如果我将函数重命名为其他任何代码,代码就会停止工作,我不明白为什么?”

:您的验证方法,必须按照validate_<field_name>中指定的会议flask-wtf在你的榜样,你的表单字段有:[用户名,电子邮件,密码,confirm_password,提交]所以您的验证方法必须是:validate_username(...)validate_email(...)validate_password(...),等...如果你想要有一个不同的验证方法名称,您还必须相应地相应地重命名您的表单字段。

希望这有帮助!