一. 编写表单类——|-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 %}