Как вы можете заполнить 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)