不是动态选择字段 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.idint - 当数据从客户端返回时,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 的有效选择的主要内容,如果未能解决你的问题,请参考以下文章

在python wtforms中选择具有动态选择值的字段。

动态选择 WTForms Flask SelectField

十三 .Flask wtforms组件和选择框动态数据实时更新

在烧瓶 wtforms jinja select 上设置动态数据属性

使用 wtforms 动态添加输入字段

使用从前一个字段中选择的值填充 WTForms 选择字段