在 wtforms 中选择字段并添加 <option>通过javascript [英] SelectField in wtforms and added <option> via javascript

查看:72
本文介绍了在 wtforms 中选择字段并添加 <option>通过javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在从事金字塔中的某个项目,但在使用 wtforms SelectField 时遇到了问题.

I'm currently work on some project in pyramid and have problem with wtforms SelectField.

我有 3 个 SelectField 字段:

I have a 3 SelectField fields:

  • car_make(例如奥迪")
  • car_model(例如奥迪 80")
  • car_version(例如AUDI 80 B4").

我可以在视图中加载的 car_make 选项.其余 SelectFields (car_model, car_version) 的选择我将通过 AJAX/javascript 在客户端加载(我可以在选择 car_make 时选择 car_model 等等).

The car_make choices I can load in the view. The choices for rest of SelectFields (car_model, car_version) I will load on the client side via AJAX/javascript (I can choose car_model when car_make is selected and so on).

问题是,当我提交表单时,car_model 和 car_version 引发无效选择",因为(在 SelectField.pre_validation 第 431 行)self.choices 为空.

The problem is that when I submit the form, car_model and car_version raise 'Not valid choice' because (in SelectField.pre_validation line 431) self.choices is empty.

我该如何解决这个问题?

How can I get around this problem?

推荐答案

您要求做的是让 WTForms 处理级联选择"(让一个选择的有效字段由另一个字段的值确定).使用内置字段确实没有什么好方法.

What you are asking to do is have WTForms handle "cascading selects" (having the valid fields of one choice be determined by the value of another field). There really isn't a good way using the built in fields.

WTForms 中的 SelectField 没有为您提供不验证所提供的选择是否有效"的选项.您必须提供选择,以便字段验证选择.

The SelectField in WTForms does NOT provide you with an option to say "Don't validate that the choice supplied is valid". You MUST provide choices in order for the field to validate the choice.

文档中所示,而您通常可以填写带有静态选择列表的选择字段...

As shown in the docs, while you typically could fill the choices field with a static list of choices...

class PastebinEntry(Form):
    language = SelectField(u'Programming Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('text', 'Plain Text')])

...但是,由于您是动态提出选项,因此您需要在实例化表单后设置 choices 属性.

...however, since you are dynamically coming up with the options, you need to set the choices attribute after instantiating the form.

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')]

在上面的示例中,group_id"的选项在您的金字塔视图中动态填充.所以,这就是您需要做的:您需要填写您的视图中的选项.这是您如何使用 car_make 解决问题的方法(尽管我认为在您的问题中您说 car_make 没问题).

In the above sample, the choices for "group_id" is filled dynamically in what would be your Pyramid view. So, that's what you would need to do: you need to fill the choices in your view. This is how you can fix your issue with car_make (although I think in your question you said that car_make was okay).

然而,您遇到的问题是无法确定 car_model 的有效选择,因为它们取决于 car_make 已经被解析和验证.WTForms 并不能很好地处理这个问题(至少对于 SelectFields),因为它假定所有字段都应该一次验证.换句话说,为了生成 car_model 的有效选择列表,您首先需要验证 car_make 的值,鉴于SelectField 有效.

The problem that you have, however, is that the valid choices for car_model cannot be determined, since they depend on car_make having already been parsed and validated. WTForms doesn't really handle this well (at least with SelectFields) because it assumes that all of the fields should be validated at once. In other words, in order to generate the list of valid choices for car_model, you first need to validate the value for car_make, which is not possible to easily do given how the SelectField works.

我认为这样做的最佳方法是创建一个新的字段类型来扩展 SelectField 类型,但删除验证:

The best way I see doing this is to create a new field type that extends the SelectField type, but removes the validation:

class NonValidatingSelectField(SelectField):
    def pre_validate(self, form):
        pass

这个新类型覆盖了 pre_validate,它通常会检查一个选项是否有效.

This new type overrides pre_validate, which typically does the check to determine if a choice is valid.

如果你将它用于 car_model,你就不会再有这个错误了.但是,这现在意味着您的字段实际上并未经过验证!要解决此问题,您可以在您的设备上添加一个内嵌验证器表格...

If you use this for car_model, you won't have the error anymore. However, this now means that your field isn't actually being validated! To fix this, you can add an in-line validator on your form...

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...

您可能需要稍微调整一下以使其完全按照您想要的方式工作,我还没有实际测试过它是否有效.

You might need to tweak this a bit to get it to work exactly how you want, I haven't actually tested that this works.

这篇关于在 wtforms 中选择字段并添加 <option>通过javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆