在上一节中完成了注册功能的前期准备工作,在这一节内容中将完成用户注册、登录功能。
1.知识预览
在本届中将学习到以下内容的知识
- 如何使用wtform来渲染表单
- 如果使用flask-mail来发送邮件
2.用户注册
在前端中form表单是用的比较多的东西,我们可以使用wtforms
这个框架,直接通过后端代码来渲染前端表单。新建bbs/forms.py
文件,嵌入以下代码
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField, BooleanField, TextAreaField, FileField, Label, HiddenField,
PasswordField
class BaseUserForm(FlaskForm):
user_name = StringField(u'用户名',
validators=[DataRequired(message='用户名不能为空'),
Length(min=1, max=16, message='用户名长度限定在1-16位之间'),
Regexp('^[a-zA-Z0-9_]*$',
message='用户名只能包含数字、字母以及下划线.')],
render_kw={
'placeholder': '请输入用户名长度1-16之间'})
nickname = StringField(u'昵称',
validators=[DataRequired(message='昵称不能为空'),
Length(min=1, max=20, message='昵称长度限定在1-20位之间')],
render_kw={
'placeholder': '请输入昵称长度1-20之间'})
user_email = StringField(u'注册邮箱',
render_kw={
'placeholder': '请输入注册邮箱', 'type': 'email'})
submit = SubmitField(u'注册', render_kw={
'class': 'btn btn-success btn-xs'})
在上面的代码中,首先导入相关的库,然后新建了一个BaseUserForm
的类,因为用户的信息在很多表单中使用到了,因此可以将共同的属性剥离出来,然后在不同的场合继承该基类,并且可以根据不同的场合在子类中定制我们的表单属性,这样就可以降低代码的冗余量。如果在每个需要使用到用户信息的表单代码中写入同样的内容,那么久显得代码很臃肿了。
BaseUserForm
类中使用到了wtforms
中的一些属性,比如StringField
就相当于是我们前端的input
标签,SubmitField
就相当于是<input type="submit">
,具体可以去看wtforms的官方文档。
继续在上面的文件中嵌入如下代码,新建注册表单类
class RegisterForm(FlaskForm):
user_name = StringField(u'用户名',
validators=[DataRequired(message='用户名不能为空'),
Length(min=1, max=16, message='用户名长度限定在1-16位之间'),
Regexp('^[a-zA-Z0-9_]*$',
message='用户名只能包含数字、字母以及下划线.')],
render_kw={
'placeholder': '请输入用户名长度1-16之间'})
nickname = StringField(u'昵称',
validators=[DataRequired(message='昵称不能为空'),
Length(min=1, max=20, message='昵称长度限定在1-16位之间')],
render_kw={
'placeholder': '请输入昵称长度1-20之间'})
user_email = StringField(u'注册邮箱',
validators=[DataRequired(message='注册邮箱不能为空'),
Length(min=4, message='注册邮箱长度必须大于4')],
render_kw={
'placeholder': '请输入注册邮箱', 'type': 'email'})
password = StringField(u'密码',
validators=[DataRequired(message='用户密码不能为空'),
Length(min=8, max=40, message='用户密码长度限定在8-40位之间'),
EqualTo('confirm_pwd', message='两次密码不一致')],
render_kw={
'placeholder': '请输入密码', 'type': 'password'})
confirm_pwd = StringField(u'确认密码',
validators=[DataRequired(message='用户密码不能为空'),
Length(min=8, max=40, message='用户密码长度限定在8-40位之间')],
render_kw={
'placeholder': '输入确认密码', 'type': 'password'})
colleges = SelectField(u'学院', choices=[(1, '计算机')])
submit = SubmitField(u'注册', render_kw={
'class': 'source-button btn btn-primary btn-xs mt-2'})
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
cols = College.query.all()
self.colleges.choices = [(col.id, col.name) for col in cols]
def validate_user_name(self, filed):
if User.query.filter_by(username=filed.data).first():
raise ValidationError('用户名已被注册.')
def validate_user_email(self, filed):
if User.query.filter_by(email=filed.data.lower()).first():
raise ValidationError('邮箱已被注册.')
def validate_n