Created
March 4, 2020 22:52
-
-
Save doobeh/aa0e07892922cfa32123a6926c7720a5 to your computer and use it in GitHub Desktop.
nested form object population
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="post" action=""> | |
{{ form.hidden_tag() }} | |
{{ form.id }} | |
{{ form.name }} | |
{% for entry in form.players %} | |
{{ entry() }} | |
{% endfor %} | |
<input type="submit"/> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ul> | |
{% for line in results %} | |
<li>{{ line }}</li> | |
{% endfor %} | |
</ul> |
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
This is useful. Thanks for putting it together so quickly!
I just now worked out what I was trying to do earlier and it might make a useful addition to your example. Either way, I'm curious to know what you think and if there are any downsides to this approach. (Mass assignment is one.)
Brought over into the context of your example, the most basic version would look something like the following: