Python WTForms: как динамически устанавливать параметры SelectField в FieldList полей формы?

В настоящее время я пытаюсь использовать вложения FieldList и FormField WTForms, чтобы пользователи могли добавлять собственное подмножество местоположений с соответствующими суммами покрытия.

Форма предоставляет пользователю некоторые стандартные входные данные, а затем инициализируется одним набором полей (FormField), каждое из которых содержит ввод выбора местоположения и ввод суммы покрытия.

Javascript позволяет пользователю добавлять или удалять дополнительные наборы полей покрытия местоположения по мере необходимости, чтобы отображать точную информацию о документе.

Проблема. В качестве обходного пути я устанавливал параметры местоположения, передавая переменную шаблона в запросе GET обработчика формы и вручную создавая свои собственные поля формы. Это не обновляет фактический выбор поля местоположения WTForms, поэтому, когда я отправляю форму, возникает исключение для поля местоположения («Недопустимый выбор»).

Как я могу динамически добавлять варианты местоположения в поле location формы LocationForm при создании экземпляра MyForm?

Вот как выглядит мой код:

Примечание. Я пропустил код, который создает переменную шаблона местоположения в запросе GET, поскольку это не соответствует действительности. Я хочу больше соответствовать предполагаемой методологии 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

Изменить:

Я создал решение, но это не тот ответ, который я ищу. В моем случае я просто изменил поле формы LocationForm.location с SelectField на StringField. Это позволяет обойти проверку выбранных полей выбора и разрешить отправку формы. Это не идеально, так как это не предполагаемый дизайн, но если кто-нибудь может направить меня к более правильному способу использования WTForms в этом конкретном сценарии, я был бы очень признателен.


person Bolezee    schedule 23.04.2014    source источник


Ответы (1)


Если ваш класс BaseForm заполняет форму из данных публикации при создании экземпляра, вы должны увидеть, что вложенные формы заполняются в том месте, где вы обычно добавляете варианты выбора в SelectField непосредственно в форме.

Поэтому что-то вроде:

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

Следует заполнить варианты выбора в каждом поле выбора подчиненной формы.

person Mark    schedule 20.12.2017