WTForms SelectMultipleFields动态默认值

3 投票
3 回答
1528 浏览
提问于 2025-04-18 15:32

我在用WTForms和Flask(不是Flask-wtf)。

我使用的是SelectMultipleFields这个功能,里面的选项是动态设置的;

class MyForm(Form):
    country = SelectMultipleField("Country", option_widget=widgets.CheckboxInput(),
       widget=widgets.ListWidget(prefix_label=False))

正如我所说,这些选项是动态的,我会查询数据库来获取新的国家,然后设置这些选项,像这样;

form = MyForm(request.form, obj=user) # obj = user's sqlalchemy object
form.country.choices = [(c.title(), c.title()) for c in get_distinct_countries()]

这里的get_distinct_countries是用来查询数据库并返回一个国家列表的,格式是[('country a', 'country a'), ('country b', 'country b', (...)]

这一切都运行得很好,但现在我想设置一个默认值,这个默认值也是动态的,所以我试了这个;

form = PersonalForm(request.form, obj=user)
form.country.choices = [(c.title(), c.title()) for c in get_distinct_countries()] # to fix
form.country.default = [(i.title(), i.title()) for i in get_user_country(userid)]

这是我的get_countriesget_user_country函数;

def get_user_country(id): # todo
    with session_scope() as session:
        countries = session.query(UserCountry).filter_by(user_id=id)
    return [c.country for c in countries.all()]

def get_distinct_countries(): # todo
    """Returns a list of all countries (without duplication)"""
    with session_scope() as session:
        countries = session.query(Country).distinct(Country.country).group_by(Country.country)
    return [i.country.capitalize() for i in countries.all()]

get_user_country的输出大概是[('country a', 'country a'), (...)]。但是没有成功,我没有收到任何错误信息,但检查表单字段时,发现没有设置默认值。我该怎么做才能让它工作呢?

需要注意的是,我传入了obj=user,因为这是一个用户重新编辑设置的表单,所以我希望数据能在那儿,显然我看到的其他数据都没问题,就是国家的数据不见了。

谢谢。

3 个回答

0

你有没有试过把default的值设置成不是元组,而是直接用索引呢?可以参考这个链接了解更多信息:just the index.

form.country.default = [i.title() for i in get_user_country(userid)]
0

我觉得WTForms在设置默认值方面挺麻烦的,因为它的工作方式和你想的不太一样。你可以通过default参数设置一个全局的默认值,但不能为每个会话单独设置。

对于简单的字段,你可以在视图中直接设置值:

@app.route('/some_route')
def flask_route():

    form = YourFormHere(obj=obj)

    form.some_field.data = "default data here"

    render_template('template.tmpl', form=form)

我不太记得我是否为SelectMultipleFields做过这个设置——我在代码里快速搜索了一下,没找到相关内容。希望这个方法对你有用。

1

我知道这个回复来得有点晚,但我在网上搜索同样的问题时找到了这个页面。正如其他用户提到的,要动态设置高亮的字段,你需要用 form.field.data 来设置,而不是 form.field.default。你想要的选择项必须放在一个列表里(即使只有一个选择)。在你提供的选择中,只使用 (value, label) 这个元组里的 "value" 部分。根据你的情况,代码应该是:

form.country.data = [i.title() for i in get_user_country(userid)]

这个方法是行不通的:

form.country.data = [(i.title(), i.title()) for i in get_user_country(userid)]

如果你想要一个单一的默认值,这个方法也不行:

form.country.data = "some value"

但这个方法是可以的:

form.country.data = ["some value"]

撰写回答