我正在阅读Flask Web Development的书,并发现了这个:
def edit_profile():
form = EditProfileForm()
if form.validate_on_submit():
current_user.name = form.name.data
current_user.location = form.location.data
current_user.about_me = form.about_me.data
db.session.add(user)
flash('Your profile has been updated.')
return redirect(url_for('.user', username=current_user.username))
form.name.data = current_user.name
form.location.data = current_user.location
form.about_me.data = current_user.about_me
return render_template('edit_profile.html', form=form)
基本上,当表单未发布或未经验证时,将复制当前用户的数据。现在阅读wtforms,我在表格中阅读了 init 方法:
obj – If formdata is empty or not provided, this object is checked for attributes
matching form field names, which will be used for field values.
所以我想这意味着我们可以写这个(下面的示例是我自己的):
def edit_post(post_id):
post = Post.query.get_or_404(post_id)
if current_user != post.author:
abort(403)
# Below is the line I am concerned about
form = PostForm(formdata=request.form, obj=post)
if form.validate_on_submit():
form.populate_obj(post)
db.session.commit()
return redirect(url_for('user', username=current_user.username))
return render_template('post_form.html', form=form)
我认为这应该从GET上的数据库模型和post后的POST数据填充表单实例。测试这个,它似乎工作..
现在我的问题是:这种编辑视图的方式是否正确?或者我应该逐字段地复制所有内容,就像在书中一样?
答案 0 :(得分:1)
在POST MultiDict
中加载肯定是将键/值对映射到WTForms实例的可接受方式。更重要的是,如果您使用的是Flask-WTF扩展程序,这将自动为您完成,这是此扩展程序为您带来的额外好处之一。
如果您要破解Flask-WTF的代码,您会看到它继承了SecureForm
类的WTForms并尝试默认加载Werkzeug POST MultiDict(称为formdata
)(如果它存在)。因此,在您的视图中加载您的表单,如下所示:
form = PostForm(obj=post)
应该足够(如果使用Flask-WTF)也用POSTed数据填充字段。
在你的书中做的方式当然没有错,但是会产生很多不必要的代码并且容易出错/冗余 - 人们可能忘记提到在WTForms实例中声明的视图中的字段。 / p>