一. 编写表单类——|-app/-main/forms.py
class EditProfileAdminForm(FlaskForm):
#首先创建表单字段, 管理员可以修改任何用户的任何属性
email = StringField('Email', validators=[DataRequired(), Length(1, 64), Email()])
username = StringField('Username', validators=[DataRequired(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, 'Username must have only letters, numbers, underscores, dots')])
confirm = BooleanField('Confirm')
role = SelectedField('Role', coerce=int)
name = StringField('Real name', validators=[Length(0, 64)])
location = StringField('Location', validators=[Length(0, 64)])
about_me = TextAreaField('About me')
submit = SubmitField('Submit')
#管理员修改用户email的时候,填写的不能是其它用户的Email, 因此Email验证函数需要知道被修改的用户, 因此我们创建表单实例的时候需要把user传进构造函数并保存下来
def __init__(self, user, *args, **kwargs):
super(EditProfileAdminForm, self).__init__(*args, **kwargs):
self.user = user
self.role.choices = [(role.id, role.name) for role in Role.query.order_by(Role.name).all()]
def validate_email(self, field):
if field.data!=self.user.email and \
User.query.filter_by(email=field.data).first():
raise ValidationError('Email has registered.')
def validate_username(self, field):
if field.data!=self.user.username and \
User.query.filter_by(username=field.data):
raise ValidationError('Username already in use.')
SelectedField的实例需要设置其choices属性, 列表中是所有角色id和name构成的元组, id是标识符, name是下拉列表显示的字符串。
把SelectField的coerce参数设置为int, 可以将其字段值设置为int, 默认是String。
二. 修改路由——|-app/-main/views.py
@main.route('/edit-profile/<int:id>', methods=['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(id):
user = User.query.get_or_404(id)
form = EditProfileAdminForm(user)
if form.validate_on_submit():
user.email = form.email.data
user.username = form.username.data
user.confirm = form.confirm.data
user.role = Role.query.get(form.role.data)
user.name = form.name.data
user.location = form.location.data
user.about_me = form.about_me.data
db.session.add(user)
flash('user profile has updated.')
return redirect(url_for('.user', username=user.username))
form.email.data = user.email
form.username.data = user.username
form.confirm.data = user.confirm
form.role.data = user.roles.id
form.name.data = user.name
form.location.data = user.location
form.about_me.data = user.about_me
return render_template('edit_profile.html', user=user, form=form)
三. 在用户资料模板中添加该路由的链接——user.html
{% if current_user.is_administrator() %}
<p><a class="btn btn-danger" href="{{ url_for('edit_profile_admin', id=user.id)}}">Edit Profile [Admin]</a></p>
{% elif current_user==user %}
<p><a class="btn btn-default" href="{{ url_for('edit_profile')}}">Edit Profile</a></p>
{% endif %}