I am following CoreyMSchafer’s Flask-blog tutorial. Here, I can create, update and delete posts using WTForms and SQLAlchemy. However, to do that, I have to explicitly mention the name of the form fields. For example, to update a post (assuming a post only has title and content):
@app.route("/post/<int:post_id>/update", methods=['GET', 'POST']) def update_post(post_id): post = Post.query.get_or_404(post_id) form = PostForm() if form.validate_on_submit(): post.title = form.title.data post.content = form.content.data db.session.commit() return redirect(url_for('post', post_id=post.id)) elif request.method == 'GET': form.title.data = post.title form.content.data = post.content return render_template('new_post.html', form=form)
where the model is
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title= db.Column(db.String, nullable=False) content= db.Column(db.String)
and the WTForm is
class SystemForm(FlaskForm): title= StringField('Title', validators=[DataRequired()]) content= StringField('Content') submit = SubmitField('Submit')
However, what if my form has hundreds of fields (such as a star which has hundreds of parameters and let’s say we want a post to store all these parameters for a star)!? Do I have to explicitly mention them in models, routes, forms – everywhere? or is it possible to create the model/form with all the fields and then somehow loop through the fields to avoid typing each of them in routes?
Advertisement
Answer
form.data returns all of the form fields and its values in dict object where dict keys is field name.
But: you may use form.populate_obj(post) method for update an object (field names in form and model must be equal)
if form.validate_on_submit(): form.populate_obj(post) db.session.commit() return redirect(url_for('post', post_id=post.id))