WTForms SelectMultipleFields动态默认值
我在用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_countries和get_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 个回答
你有没有试过把default
的值设置成不是元组,而是直接用索引呢?可以参考这个链接了解更多信息:just the index.
form.country.default = [i.title() for i in get_user_country(userid)]
我觉得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做过这个设置——我在代码里快速搜索了一下,没找到相关内容。希望这个方法对你有用。
我知道这个回复来得有点晚,但我在网上搜索同样的问题时找到了这个页面。正如其他用户提到的,要动态设置高亮的字段,你需要用 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"]