在 Flask-WTF 中填充表单和选择默认值
Populating forms and selecting defaults in Flask-WTF
我有一个用于撰写和编辑博客 post 的表单,如下所示:
class EditorForm(FlaskForm):
title = StringField('Title', validators=[DataRequired(), Length(min=1, max=250)])
body = PageDownField('Body', validators=[DataRequired()])
tags = SelectMultipleField('Tags', coerce=int)
timestamp = DateTimeField('Timestamp')
published = BooleanField('Publish?')
update = BooleanField('Update Timestamp?')
delete = SubmitField('Delete')
submit = SubmitField('Save')
在我看来,我区分编辑现有 post 和创建新的。对于现有的 post,如果它们有关联的标签,我希望它们在表单的 SelectMultipleField
中突出显示,以便用户可以看到它们。
如果这些被突出显示并且我想删除标签,我需要能够取消突出显示并提交表单来执行此操作。
以下是我目前观点的相关部分:
@app.route('/editor/<slug>', methods=['GET', 'POST'])
@app.route('/editor/', methods=['GET', 'POST'])
@login_required
def editor(slug=None):
# old post or new post?
if slug:
post = Post.query.filter_by(slug=slug).first()
else:
post = Post()
# populate form, blank for new post
form = EditorForm(obj=post)
# populate tags field
form.tags.choices = [(tag.id, tag.tag) for tag in Tag.query.order_by('tag')]
# declare list for tag highlights on GET
if request.method == 'GET':
form.tags.default = []
# if post has linked tags, highlight them
if post.tags:
for tag in post.tags:
if tag.id not in form.tags.default:
form.tags.default.append(tag.id)
form.process()
在寻找与我的问题相关的 other questions 时,我发现我不能直接使用 form.tags.data
来突出显示关联的标签,因为这意味着该字段忽略了用户在表单上的操作,即使正确的选择会突出显示。这就是我使用 form.tags.default
.
的原因
form.tags.default
似乎可以突出显示正确的标签,但 form.process()
会擦除由 form = EditorForm(obj=post)
.
填写的所有其他字段
所以我的问题是:如何使用现有 post 数据填充我的表单并在同一实例中突出显示正确的标签?
这个问题我好像得到了我想要的结果。我原来的部分问题实际上与我在问题中没有 post 的一些代码有关。
在 if form.validate_on_submit():
,我将 form.tags.data
中的标签(突出显示的选项)附加到我的 post.tags
。
在 post 已经附加标签的情况下,这意味着取消选择字段中的默认值确实会根据需要清空 form.tags.data
,但是 post.tags
仍然有原始数据,因此没有变化。
已通过以下方式解决:
# empty tags list then add highlighted choices
post.tags = []
for id in form.tags.data:
t = Tag.query.filter_by(id=id).first()
post.tags.append(t)
我还更改了填充表单的代码,使其更简单。我错了需要使用 default
而不是 data
(坦率地说,我不明白两者之间的区别):
# populate form, blank for new post
form = EditorForm(obj=post)
# populate tags field
form.tags.choices = [(tag.id, tag.tag) for tag in Tag.query.order_by('tag')]
# populate defaults only on GET otherwise user choice overidden
if request.method == 'GET':
# declare default (highlighted) tags list
form.tags.data = []
# if post has tags, highlight them
if post.tags:
for tag in post.tags:
form.tags.data.append(tag.id)
我有一个用于撰写和编辑博客 post 的表单,如下所示:
class EditorForm(FlaskForm):
title = StringField('Title', validators=[DataRequired(), Length(min=1, max=250)])
body = PageDownField('Body', validators=[DataRequired()])
tags = SelectMultipleField('Tags', coerce=int)
timestamp = DateTimeField('Timestamp')
published = BooleanField('Publish?')
update = BooleanField('Update Timestamp?')
delete = SubmitField('Delete')
submit = SubmitField('Save')
在我看来,我区分编辑现有 post 和创建新的。对于现有的 post,如果它们有关联的标签,我希望它们在表单的 SelectMultipleField
中突出显示,以便用户可以看到它们。
如果这些被突出显示并且我想删除标签,我需要能够取消突出显示并提交表单来执行此操作。
以下是我目前观点的相关部分:
@app.route('/editor/<slug>', methods=['GET', 'POST'])
@app.route('/editor/', methods=['GET', 'POST'])
@login_required
def editor(slug=None):
# old post or new post?
if slug:
post = Post.query.filter_by(slug=slug).first()
else:
post = Post()
# populate form, blank for new post
form = EditorForm(obj=post)
# populate tags field
form.tags.choices = [(tag.id, tag.tag) for tag in Tag.query.order_by('tag')]
# declare list for tag highlights on GET
if request.method == 'GET':
form.tags.default = []
# if post has linked tags, highlight them
if post.tags:
for tag in post.tags:
if tag.id not in form.tags.default:
form.tags.default.append(tag.id)
form.process()
在寻找与我的问题相关的 other questions 时,我发现我不能直接使用 form.tags.data
来突出显示关联的标签,因为这意味着该字段忽略了用户在表单上的操作,即使正确的选择会突出显示。这就是我使用 form.tags.default
.
form.tags.default
似乎可以突出显示正确的标签,但 form.process()
会擦除由 form = EditorForm(obj=post)
.
所以我的问题是:如何使用现有 post 数据填充我的表单并在同一实例中突出显示正确的标签?
这个问题我好像得到了我想要的结果。我原来的部分问题实际上与我在问题中没有 post 的一些代码有关。
在 if form.validate_on_submit():
,我将 form.tags.data
中的标签(突出显示的选项)附加到我的 post.tags
。
在 post 已经附加标签的情况下,这意味着取消选择字段中的默认值确实会根据需要清空 form.tags.data
,但是 post.tags
仍然有原始数据,因此没有变化。
已通过以下方式解决:
# empty tags list then add highlighted choices
post.tags = []
for id in form.tags.data:
t = Tag.query.filter_by(id=id).first()
post.tags.append(t)
我还更改了填充表单的代码,使其更简单。我错了需要使用 default
而不是 data
(坦率地说,我不明白两者之间的区别):
# populate form, blank for new post
form = EditorForm(obj=post)
# populate tags field
form.tags.choices = [(tag.id, tag.tag) for tag in Tag.query.order_by('tag')]
# populate defaults only on GET otherwise user choice overidden
if request.method == 'GET':
# declare default (highlighted) tags list
form.tags.data = []
# if post has tags, highlight them
if post.tags:
for tag in post.tags:
form.tags.data.append(tag.id)