如何用烧瓶/wtforms正确地预填充子表单值



我正在编写一个小型应用程序,它由利用flask_wtf的表单和子表单组成。我希望在用户开始编辑之前用已知值(来自json(预填充表单。尽管有很多搜索,但大多数文档或示例/问题都不包括子表单,也不涉及在用户提交后动态更新子表单。

下面的代码演示了我迄今为止所做的尝试。除了populate_obj之外,它似乎还能工作。我可以通过传递"obj=my_data(("来预填充主表单,但还没有发现如何构造obj来填充子表单。我也可以通过setting.data进行更新,但我在其他任何地方都没有看到这种使用(form.subform.form.name.data="x"(更新子表单的方法,所以我强烈怀疑它是不正确的。

感谢任何帮助/见解。

app.py

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, FormField
from wtforms.validators import InputRequired, Length
app = Flask(__name__)
app.config["SECRET_KEY"] = "Mysecret!"

class sub_form(FlaskForm):
favorite_food = StringField(
"Favorite Food",
validators=[
InputRequired("A entry is required!"),
Length(min=4, max=20, message="Entry must be between 4 and 20 characters"),
],
default="Pineapple",
)

class main_form(FlaskForm):
user_name = StringField(
"Your name",
validators=[
InputRequired("Field is required!"),
Length(min=4, max=20, message="Name must be between 4 and 20 characters"),
],
)
first_subform = FormField(sub_form)

class name:
user_name = "Bert"

class fruit:
favorite_food = "bananas"

@app.route("/", methods=["GET", "POST"])
def index():
# Create the main form, populate name with "Bert"
form = main_form(obj=name())
# Update the main form user_name with "Ernie"
form.user_name.data = "Ernie"
# Update the sub form favorite food with "oranges".I suspect this is not optimal. 
form.first_subform.form.favorite_food.data = "oranges"
return render_template("index_test.html", form=form)

if __name__ == "__main__":
app.run(debug=True)

index_test.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<form action="/" method="POST">
{{ form.csrf_token }}
{{form.user_name.label}}  {{form.user_name(size=20)}}
<br>
{{form.first_subform.favorite_food.label}}  {{form.first_subform.favorite_food(size=20)}}
<br>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>

虽然wtforms可以嵌套,并且嵌套的表单数据可以使用form.Level1Form.form.Level2Form.name.data等格式访问,但这种方法会给建模等带来下游挑战。我得出的结论是,最好保持表单的独立性,并使用这样的多视图来呈现表单:

返回render_template('index.html',register_form=register_form,login_form=login_form(

引用自此问题的更新答案。

最新更新