Skip to content

Instantly share code, notes, and snippets.

@doobeh
Created March 4, 2020 22:52
Show Gist options
  • Save doobeh/aa0e07892922cfa32123a6926c7720a5 to your computer and use it in GitHub Desktop.
Save doobeh/aa0e07892922cfa32123a6926c7720a5 to your computer and use it in GitHub Desktop.
nested form object population
<form method="post" action="">
{{ form.hidden_tag() }}
{{ form.id }}
{{ form.name }}
{% for entry in form.players %}
{{ entry() }}
{% endfor %}
<input type="submit"/>
</form>
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, FormField, FieldList, IntegerField
app = Flask(__name__)
app.secret_key = "SCRATCH"
# Our pretend object data (I'd use SQLAlchemy to do this in reality).
class TeamObj(object):
id = 0
name = ""
class PlayerObj(object):
id = 0
name = ""
pa = PlayerObj()
pa.name = "Carol"
pa.id = 1
pb = PlayerObj()
pb.name = "Jane"
pb.id = 2
# SQLAlchemy might be: team = Team.query.get(2)
team = TeamObj()
team.name = "Bombers"
team.id = 2
team.players = [pa, pb]
class PlayerForm(FlaskForm):
name = StringField("Player Name")
id = IntegerField("id")
class TeamForm(FlaskForm):
id = IntegerField("Team ID")
name = StringField("Team Name")
players = FieldList(
FormField(PlayerForm, default=PlayerObj), min_entries=7, max_entries=7
)
@app.route("/", methods=["post", "get"])
def home():
results = []
form = TeamForm(obj=team)
if form.validate_on_submit():
results = []
for idx, data in enumerate(form.players.data):
results.append(data)
results.append(form.name.data)
return render_template("results.html", results=results)
print(form.errors)
return render_template("home.html", form=form)
if __name__ == "__main__":
app.run(debug=True)
<ul>
{% for line in results %}
<li>{{ line }}</li>
{% endfor %}
</ul>
@doobeh
Copy link
Author

doobeh commented Mar 5, 2020

Yeah, I think I end up in the same place pretty much-- feels like there's improvements to be had though, will be pondering it for a while 😄 🤔

if form.validate_on_submit():
    team = Team(name=form.name.data)
    for player_data in form.players.data:
        # maybe some validation here to trim any 'default' entries.
        if len(player_data["name"]):
            p = Player(
                name=player_data["name"],
                age=player_data["age"],
                team=team
            )
    db.session.add(team)
    db.session.commit()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment