简体   繁体   English

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

[英]Populating forms and selecting defaults in Flask-WTF

I have a form that is used for composing and editing blog posts like this:我有一个用于撰写和编辑博客文章的表单,如下所示:

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

In my view I distinguish between editing existing posts and creating new ones.在我看来,我区分了编辑现有帖子和创建新帖子。 For existing posts, if they have associated tags, I want these to be highlighted in the SelectMultipleField on the form so the user can see them.对于现有的帖子,如果它们有关联的标签,我希望它们在表单的SelectMultipleField突出显示,以便用户可以看到它们。

If these are highlighted and I want to remove the tags, I need to be able to unhighlight them and submit the form to do so.如果这些突出显示并且我想删除标签,我需要能够取消突出显示它们并提交表单来这样做。

Here are the relevant parts of my view as it stands now:以下是我目前观点的相关部分:

@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()

In fishing around other questions related to my issue, I have discovered that I can't directly use form.tags.data to highlight associated tags because this means user action on the form is ignored for that field, even though the right choices will be highlighted.在寻找与我的问题相关的其他问题时,我发现我不能直接使用form.tags.data来突出显示关联的标签,因为这意味着该字段的表单上的用户操作将被忽略,即使正确的选择是突出显示。 This is why I am using form.tags.default .这就是我使用form.tags.default

form.tags.default seems to work for highlighting the correct tags, BUT form.process() wipes all the other fields filled out by form = EditorForm(obj=post) . form.tags.default似乎可以突出显示正确的标签,但form.process()擦除由form = EditorForm(obj=post)填写的所有其他字段。

So my question is: how can I populate my form with existing post data AND highlight the right tags in the same instance?所以我的问题是:如何使用现有的帖子数据填充我的表单并在同一实例中突出显示正确的标签?

I seem to have obtained the result I wanted with this issue.我似乎已经通过这个问题获得了我想要的结果。 Part of my original problem was actually related to some code in the view that I didn't post in my question.我的原始问题的一部分实际上与我没有在我的问题中发布的视图中的一些代码有关。

On if form.validate_on_submit(): , I was appending the tags in form.tags.data (highlighted choices) to my post.tags .if form.validate_on_submit(): ,我将form.tags.data (突出显示的选项)中的标签附加到我的post.tags In cases where posts already had attached tags this meant that deselecting the defaults in the field was indeed emptying form.tags.data as desired, but post.tags still had the original data anyway, hence no change.在帖子已经附加标签的情况下,这意味着取消选择字段中的默认值确实form.tags.data根据需要清空form.tags.data ,但post.tags仍然具有原始数据,因此没有变化。

This was solved with the following:这是通过以下方式解决的:

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

I also changed my code that populated the form to be simpler.我还将填充表单的代码更改为更简单。 I was wrong about needing to use default over data (and frankly I don't understand the difference between the two):我错了需要对data使用default (坦率地说,我不明白两者之间的区别):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM