Как вы можете заполнить WTForms FieldList после блока validate_on_submit()?

Существует реальная нехватка документации о том, как работать с FieldList WTForms. Так что благодаря Интернету я смог взломать следующее:

Форма:

class BranchForm(Form):
    name = StringField('Name', validators = [Required()])
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
        choices = [(x.id, x.name) for x in Equipment.query.all()]))
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))

Посмотреть:

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()

    #populate data_in to be used by BranchForm
    data_in = []
    for eq_obj in branch.equipment_assoc:
        data_in.append(('equipment', eq_obj.equipment.id))
        data_in.append(('mod', eq_obj.mod))

    editform = BranchForm(data=MultiDict(data_in))

    if editform.validate_on_submit():
        branch.name = editform.name.data

        db.session.add(branch)
        db.session.commit()

        return redirect('/admin/branches/' + str(branch.id))

    editform.name.data = branch.name

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)

Что меня отталкивает, так это то, что везде, где я использовал форму WTForm и заполнял поля данными из моей базы данных (например, для редактирования форм), мне приходилось заполнять эти поля формы после блока form.validate_on_submit(), потому что если нет, то форма никогда не будет обновляться, поскольку все, что отправлено, будет немедленно перезаписано.

Смотрите "editform.name.data = branch.name" (так я всегда это делал)

Из каждого примера, который я нашел в Интернете о заполнении FieldList, это, очевидно, должно быть сделано во время создания экземпляра, но экземпляр формы должен быть создан до validate_on_submit (), а также потому, что validate_on_submit () является методом объекта формы.

Смотрите "editform = BranchForm(data=MultiDict(data_in))" "(вот как я видел FieldLists, заполненные во всех примерах, которые я видел.)

Как я могу заполнить форму списками полей?

2 ответа

Решение

Хорошо, приятель помог мне разобраться с этим. Вот чем я закончил:

Форма:

class BranchForm(Form):
    name = StringField('Name', validators = [Required()])
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
        choices = [(x.id, x.name) for x in Equipment.query.all()]))
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))

    def populate_assoc(self, branch_obj):
        i = 0
        branch_obj.name = self.name.data
        for assoc_obj in branch_obj.equipment_assoc:
            assoc_obj.equipment_id = self.equipment[i].data
            assoc_obj.mod = self.mod[i].data
            i += 1

Посмотреть:

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()

    if request.method == 'POST':
        editform = BranchForm()

        if editform.validate_on_submit():
            editform.populate_assoc(branch)

            db.session.add(branch)
            db.session.commit()

            return redirect('/admin/branches/' + str(branch.id))

    #populate data_in to be used 
    data_in = []
    for eq_obj in branch.equipment_assoc:
        data_in.append(('equipment', eq_obj.equipment.id))
        data_in.append(('mod', eq_obj.mod))

    editform = BranchForm(data=MultiDict(data_in))
    editform.name.data = branch.name

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)

Хитрость была в том, чтобы отойти от использования form.validate_on_submit() в качестве логического разделителя, поскольку он опирается на объект формы. Его идея заключалась в том, чтобы использовать if request.method == 'POST': для этой цели. Таким образом, я могу создать свою форму двумя разными способами. Один заполняется для отображения, другой создается только в том случае, если метод запроса POST, сохраняя информацию, представленную в форме.

Чтобы завершить работу, я добавил метод populate_assoc в свой класс формы, чтобы я мог легко поместить информацию из формы в мою модель ассоциации.

WtForms имеет метод populate_obj(). Может быть, это то, что вы после?

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()
    editform = BranchForm(obj=branch)
    if editform.validate_on_submit():
        editform.populate_obj(branch)

        db.session.commit()

        return redirect('/admin/branches/' + str(branch.id))

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)
Другие вопросы по тегам