Reputation: 323
c.ingredientsI am creating a Flask sample app for learning purposes and I have a Form called CocktailForm that contains a SelectMultipleField. This form should be used for creating new cocktails objects as well as for updating them:
class CocktailForm(Form):
name = StringField('What is the coktail\'s name?', validators=[Required()])
ingredients = SelectMultipleField('Ingredients',
coerce=int,
)
submit = SubmitField('Submit')
For editing I want to load the same form with the cocktail data. It works for name, and for loading all choices but I also want to select those choices that are ingredients of that cocktail:
@main.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit(id):
try:
c = Cocktail.query.filter(Cocktail.id == id).one()
form = CocktailForm()
form.ingredients.choices = [(i.id, i.name) for i in Ingredient.query.all()]
if form.validate_on_submit():
c.name = form.name.data
cocktail_ingredients = Ingredient.query.filter(Ingredient.id.in_(form.ingredients.data)).all()
c.ingredients.extend(cocktail_ingredients)
db.session.commit()
else:
form.name.data = c.name
form.ingredients.default = [(i.id, i.name) for i in c.ingredients]
return render_template('new.html', form=form)
except Exception, e:
print e
return redirect(url_for('.index'))
I get unexpected results since on the HTML those choices are not displayed but when I submit the form it seems like those choices are always selected even if you select a new ones.
The template is quite simple:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Cocktails{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>New Cocktail</h1>
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
This is what you can see in in the browser. I am editing Gintonic cocktail which is composed of gin and tonic. However they are not displayed as selected:
Thanks in advance, any tip will be appreciated
Upvotes: 1
Views: 1252
Reputation: 621
The line form.ingredients.default = [(i.id, i.name) for i in Ingredient.query.all()]
does not set the selected values. You want to change it to be form.ingredients.data = [i.id for i in c.ingredients]
.
You should have a redirect/render_template in the validate block, but that is optional.
Upvotes: 4