qwe*_*tty 7 python wtforms pyramid
我目前正在金字塔中的某个项目上工作,并且在wtforms SelectField方面存在问题.
我有一个3个SelectField字段:
我可以在视图中加载car_make选项.其余SelectFields(car_model,car_version)的选择我将通过AJAX/javascript在客户端加载(我可以在选择car_make时选择car_model等等).
问题是,当我提交表单时,car_model和car_version会引发"无效选择",因为(在SelectField.pre_validation第431行中)self.choices为空.
我怎样才能解决这个问题?
Mar*_*eth 13
你要做的是让WTForms处理"级联选择"(具有一个选择的有效字段由另一个字段的值确定).使用内置字段确实没有好办法.
WTForms中的SelectField没有为您提供"不验证所提供的选项是否有效"的选项.您必须提供选择,以便该字段验证选择.
如文档中所示,虽然您通常可以使用静态选项列表填充选项字段...
class PastebinEntry(Form):
language = SelectField(u'Programming Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('text', 'Plain Text')])
Run Code Online (Sandbox Code Playgroud)
...但是,由于您是动态提出选项,因此需要choices在实例化表单后设置属性.
def edit_user(request, id):
user = User.query.get(id)
form = UserDetails(request.POST, obj=user)
form.group_id.choices = [(g.id, g.name) for g in Group.query.order_by('name')]
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,"group_id"的选项会在您的Pyramid视图中动态填充.所以,这就是你需要做的事情:你需要在你的视图中填写选项.这就是你如何解决你的问题car_make(尽管我认为在你的问题中你说这car_make没关系).
但是,您遇到的问题是car_model无法确定有效选项,因为它们取决于car_make已经过解析和验证.WTForms并不能很好地处理这个问题(至少使用SelectFields),因为它假定所有字段都应该立即验证.换句话说,为了生成有效选择列表car_model,首先需要验证值car_make,这对于SelectField如何工作是不可能的.
我看到这样做的最好方法是创建一个扩展SelectField类型的新字段类型,但删除验证:
class NonValidatingSelectField(SelectField):
def pre_validate(self, form):
pass
Run Code Online (Sandbox Code Playgroud)
这种新类型会覆盖pre_validate,它通常会进行检查以确定选择是否有效.
如果您使用此功能car_model,则不会再出现错误.但是,现在这意味着您的字段实际上并未经过验证!要解决此问题,您可以在表单上添加内联验证器 ...
class MyForm(Form):
car_make = SelectField(u'Make', choices=[...])
car_model = NonValidatingSelectField(u'Model', choices=[])
def validate_car_model(self, field):
choices = query_for_valid_models(self.car_make.data)
# check that field.data is in choices...
Run Code Online (Sandbox Code Playgroud)
您可能需要稍微调整一下以使其按照您想要的方式工作,我实际上没有测试过它的工作原理.