文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
修复用户名重复的 BUG
利用用户名重复 BUG 这么久, 现在时候向你展示如何修复它了。
你是否还记得, RegistrationForm
已经实现了对用户名的验证,但是编辑表单的要求稍有不同。 在注册期间,我需要确保在表单中输入的用户名不存在于数据库中。 在编辑个人资料表单中,我必须做同样的检查,但有一个例外。 如果用户不改变原始用户名,那么验证应该允许,因为该用户名已经被分配给该用户。 下面你可以看到我为这个表单实现了用户名验证:
class EditProfileForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
about_me = TextAreaField('About me', validators=[Length(min=0, max=140)])
submit = SubmitField('Submit')
def __init__(self, original_username, *args, **kwargs):
super(EditProfileForm, self).__init__(*args, **kwargs)
self.original_username = original_username
def validate_username(self, username):
if username.data != self.original_username:
user = User.query.filter_by(username=self.username.data).first()
if user is not None:
raise ValidationError('Please use a different username.')
该实现使用了一个自定义的验证方法,接受表单中的用户名作为参数。 这个用户名保存为一个实例变量,并在 validate_username()
方法中被校验。 如果在表单中输入的用户名与原始用户名相同,那么就没有必要检查数据库是否有重复了。
为了使得新增的验证方法生效,我需要在对应视图函数中添加当前用户名到表单的 username 字段中:
@app.route('/edit_profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
form = EditProfileForm(current_user.username)
# ...
现在这个 BUG 已经修复了,大多数情况下,以后在编辑个人资料时出现用户名重复的提交将被友好地阻止。 但这不是一个完美的解决方案,因为当两个或更多进程同时访问数据库时,这可能不起作用。假如存在验证通过的进程 A 和 B 都尝试修改用户名为同一个,但稍后进程 A 尝试重命名时,数据库已被进程 B 更改,无法重命名为该用户名,会再次引发数据库异常。 除了有很多服务器进程并且非常繁忙的应用之外,这种情况是不太可能的,所以现在我不会为此担心。
此时,你可以尝试再次重现该错误,以了解新的表单验证方法如何防止该错误。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论