在Flask-WTF中填充表单并选择默认值

时间:2020-08-24 18:44:11

标签: python flask flask-wtforms wtforms

我有一个用于撰写和编辑博客帖子的表格,如下所示:

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')

在我看来,我区分编辑现有帖子和创建新帖子。对于现有帖子,如果它们具有关联的标签,我希望在表单上的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)填写的所有其他字段。

所以我的问题是:如何用现有的帖子数据填充表单并在同一实例中突出显示正确的标签?

1 个答案:

答案 0 :(得分:0)

对于此问题,我似乎已经获得了想要的结果。出于我未在问题中发布的观点,我最初问题的一部分实际上与某些代码有关。

if form.validate_on_submit():上,我将form.tags.data(突出显示的选项)中的标签附加到我的post.tags上。 如果帖子中已经带有标签,则意味着取消选择该字段中的默认值确实是根据需要清空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)
相关问题