【问题标题】:FlaskForm Validation Code: checking if a user already exists or notFlaskForm 验证码:检查用户是否已经存在
【发布时间】:2019-02-07 21:52:40
【问题描述】:

所以当我来到关于在注册帐户时检查用户名或电子邮件是否已被使用的部分时,我正在关注 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.')

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

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

【问题讨论】:

  • 你是如何导入用户的?

标签: python flask flask-sqlalchemy flask-wtforms


【解决方案1】:

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

你的表单定义是用这段代码给出的:

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

这是在屏幕上创建表单的 UI最终用户在注册时看到的内容。这个表单创建是通过flask_wtf 库完成的,并在Jinja2 的帮助下呈现在一个html 页面中。 Jinja2 是一个模板引擎,Python 可以利用它来为服务器端页面提供动态数据。 现在这个表单定义中的变量是什么意思? [用户名、电子邮件、密码、confirm_password、提交]这些是对表单字段的引用。例如,当用户输入他们的信息以在您的站点上注册一个帐户时,他们使用的用户名可以通过引用 form.username.data 字段来访问。同样,要获取他们使用的密码,进行注册,您必须引用form.password.data 字段等等......验证函数:validate_username(...)validate_email(..) 是您在您的RegistrationForm(FlaskForm) 类在用户通过单击Sign Up 按钮提交其帐户详细信息时验证用户emailusername唯一性。如果另一个用户已经在使用此用户名或电子邮件,则会引发错误那么这是如何完成的?验证由您在 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}')"

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

现在回答你的问题:

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

答案:这些只是函数参数变量,可以随意命名,因为您将用户名(或电子邮件)表单字段直接传递给函数通过函数声明。即 validate_<field_name>

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

回答: 您的验证方法必须遵循 flask-wtf 中指定的 validate_<field_name> 约定在您的示例中,您的表单字段为:[username, email, password, confirm_password, submit]所以您的验证方法必须是:validate_username(...)validate_email(...)validate_password(...) 等...如果您想要使用不同的验证方法名称,您还必须相应地重命名表单字段。

希望对您有所帮助!

【讨论】:

  • 非常感谢您的详尽解释,真的让我明白了很多!祝福!
  • np,很高兴它有帮助
  • +1 感谢您的解释。对于任何感兴趣的人,这些被称为在线验证器。在此处阅读更多信息wtforms.readthedocs.io/en/3.0.x/forms/…
猜你喜欢
  • 1970-01-01
  • 2015-05-05
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
相关资源
最近更新 更多