不是动态选择字段 WTFORMS 的有效选择
Posted
技术标签:
【中文标题】不是动态选择字段 WTFORMS 的有效选择【英文标题】:Not a Valid Choice for Dynamic Select Field WTFORMS 【发布时间】:2012-12-07 11:59:43 【问题描述】:我目前正在使用 WTFORMS 创建一个动态选择字段,但是它从不提交并且验证失败并出现以下错误。
Not a valid choice
我的字段是这样创建的:
area = SelectField()
在视图中,我正在从数据库中获取选项,如下所示:
form = MytestForm()
form.area.choices = [(a.id, a.name) for a in Area.objects.all()]
但是,如果我创建静态选项,它会起作用。
【问题讨论】:
【参考方案1】:我的猜测是 Area.id
是 int
- 当数据从客户端返回时,WTForms 会将其视为 字符串,除非将可调用对象传递给 coerce
关键字参数wtforms.fields.SelectField
构造函数的:
area = SelectField(coerce=int)
或者,如果您使用的是 SQLAlchemy,则可以使用 wtforms.ext.sqlalchemy.fields.QuerySelectField
(如果您使用的是 WTForms 3+,则为 wtforms_sqlalchemy
):
area = QuerySelectField(query_factory=Area.objects.all,
get_pk=lambda a: a.id,
get_label=lambda a: a.name)
【讨论】:
嗨,肖恩,感谢您的回复。但是我使用的是mongodb,所以id实际上是一个字符串。 感谢这是强制问题,WTFORMS 默认转换为 unicode,但实际对象是 MongoDB 对象 ID 类型。所以我改变了强制创建一个 ObjectID 实例,它现在验证了。 coerce=int 为我修复了它。具体来说,我的问题是我的选择值恰好是整数 0 和 1。我的猜测是 wtforms 将其解释为 False 和 True。但是,我的模型需要一个 int。类 Abc(Base): foo = Column(Integer) 类 AbcView(ModelView): form_overrides = 'foo': SelectField, form_args = 'foo': 'choices': [ (0, 'unknown'), ( 1, 'defcon 1') ], 'coerce': int 亲爱的@SeanVieira 非常感谢您提供 wtforms.ext.sqlalchemy.fields.QuerySelectField。它救了我一辈子:) coerce=int - 为我工作,但在其他情况下。谢谢!【参考方案2】:下面是在没有 QuerySelectField 的情况下如何解决它的方法。
我是这样做的:
years = [(str(y), y) for y in reversed(range(1950, 2013))]
years.insert(0, ('','year'))
year = wt.SelectField(choices=years)
【讨论】:
【参考方案3】:请记住在设置 Form 类时也提供可用的选项。
class MyForm(FlaskForm):
sel = SelectField(coerce=int, label="MyLabel", choices=my_choices)
....
选择可以是这样的:
my_choices = [x.id for x in get_products()]
当调用validate_on_submit()
函数时,脚本/wtforms/fields/core.py
中的函数pre_validate
出现异常
【讨论】:
以上是关于不是动态选择字段 WTFORMS 的有效选择的主要内容,如果未能解决你的问题,请参考以下文章
动态选择 WTForms Flask SelectField
十三 .Flask wtforms组件和选择框动态数据实时更新