简体   繁体   English

Python WTForms:如何在FormFields的FieldList中动态设置SelectField的选项?

[英]Python WTForms: How to dynamically set options of a SelectField in FieldList of FormFields?

I am currently trying to use WTForms 's FieldList and FormField enclosures to allow users to add a custom subset of locations with corresponding coverage amounts. 我目前正在尝试使用WTFormsFieldListFormField附件,以允许用户添加具有相应覆盖范围的位置的自定义子集。

The form presents a user with some standard inputs and then initializes with a single set of fields (FormField) each with a location select input and a coverage amount input. 该表单向用户提供一些标准输入,然后使用一组字段(FormField)进行初始化,每个字段都包含一个位置选择输入和一个覆盖量输入。

Javascript allows the user to add or remove additional location coverage field sets as needed to reflect the accurate document information. Javascript允许用户根据需要添加或删除其他位置覆盖字段集,以反映准确的文档信息。

The Problem: As a workaround, I have been setting the location options by passing a template variable in the form handler's GET request and manually creating my own form fields. 问题:作为一种解决方法,我通过在表单处理程序的GET请求中传递模板变量并手动创建自己的表单字段来设置位置选项。 This isn't updating the actual WTForms location field choices though, so when I submit the form an exception is raised for the location field ('Not a valid choice'). 但是,这并没有更新实际的WTForms位置字段选择,因此,当我提交表单时,会为位置字段引发一个异常(“无效选择”)。

How can I dynamically add location choices to the location field of the LocationForm when I instantiate MyForm ? 实例化MyForm时,如何动态地将位置选择添加到LocationForm的location字段中?

This is basically how my code looks: 这基本上就是我的代码的样子:

Note: I have omitted the code that creates a locations template variable in the GET request since that is not the desired design. 注意:由于这不是理想的设计,因此我省略了在GET请求中创建位置模板变量的代码。 I want to be more in line with the intended WTForms methodology : 我想更符合预期的WTForms方法

class LocationForm(Form):
    location = SelectField('Location', [], choices=[])
    coverage = FloatField('Coverage', [])

class MyForm(BaseForm):
    # other fields omitted for brevity
    location_coverage = FieldList(FormField(LocationForm), [], min_entries=1)

class AddDocument(BaseHandler):

    def get(self):
        params = {
           "cid": cid
        }
        return self.render_template("form.html", **params)

    def post(self):
        cid = self.request.get('cid')
        if not self.form.validate():
            return self.get()
        company_key = ndb.Key('Company', cid)
        doc = Document(parent=company_key)
        self.form.populate_obj(doc)
        doc.put()
        params = { 
            "cid": 
        }
        return self.redirect_to('view_company', **params)

    @webapp2.cached_property
    def form(self):
        f = MyForm(self)

        # HERE is where I would normally do something like:
        # company = ndb.Key('Company', int(self.request.get('cid')))
        # locations = ndb.Location.query(ancestor=company).fetch() 
        # f.field_name.choices = [(loc.key, loc.name) for loc in locations]
        # but this doesn't work with Select Fields enclosed in 
        # FormFields and FieldLists.

        return f

Edit: 编辑:

I created a solution but this isn't the answer I am looking for. 我创建了一个解决方案,但这不是我想要的答案。 In my case, I simply changed the LocationForm.location form field from a SelectField to a StringField. 就我而言,我只是将LocationForm.location表单字段从SelectField更改为StringField。 Doing this bypasses the validation of the select field choices and allows the form to submit. 这样做绕过了选择字段选择的验证,并允许表单提交。 This is not ideal as it is not the intended design, but if anyone can steer me toward a more proper way to use WTForms in this particular scenario I would greatly appreciate it. 这不是理想的设计,因为它不是预期的设计,但是如果有人可以引导我寻求在这种特定情况下使用WTForms的更正确方法,我将不胜感激。

If your BaseForm class populates the form from the post data on instantiation, you should see the nested forms populated at the point where you'd normally add the choices into a SelectField directly on the form. 如果您的BaseForm类从实例化后的发布数据中填充表单,则应该看到通常在将选择直接添加到表单的SelectField的位置处填充的嵌套表单。

Therefore something like: 因此类似:

for entry in f.location_coverage.entries:
    entry.location.choices = [(loc.key, loc.name) for loc in locations]

Should populate the choices into each subform select field. 应该将选择填充到每个子表单选择字段中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM