How can you populate the WTForms field list after the validate_on_submit () block?

There is a real lack of documentation on how to work with the WTForms field list. Therefore, thanks to the Internet, I was able to hack the following:

the form:

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

View:

 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) 

What throws me away is that wherever I used the WTForm form and filled the fields with data from my db (for example, for editing forms), I had to fill these form fields after form.validate_on_submit (), because if not, then the form will never be updated, since everything that is submitted is immediately overwritten.

See "editform.name.data = branch.name" (as I always did)

From every example that I found on the Internet about populating a FieldList, it apparently should be executed at the time the instance was created, but the form must be created before validate_on_submit (), and because validate_on_submit () is a form object method.

See "editform = BranchForm (data = MultiDict (data_in)") (this is how I saw FieldLists populated in all the examples I saw.)

How can I fill out my form with lists of fields?

+5
source share
2 answers

Okay, so a friend helped me figure this out. Here is what I ended up with:

the form:

 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 

View:

 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) 

The trick was to step aside from using form.validate_on_submit () as my logical separator, as it relies on a form object. His idea was to use if request.method == 'POST': for this purpose. Thus, I can create my form in two ways. One of them is filled in for display, the other is only an instance if the request method is POST, thus preserving the information presented in the form.

To complete the task, I added the populate_assoc method to my form class so that I can easily place information from the form in my association model.

0
source

WtForms has a populate_obj () method. Maybe what are you after?

 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) 
0
source

All Articles