Home > Software design >  How to collect WTForms data through loop without explicitly stating the name of each field?
How to collect WTForms data through loop without explicitly stating the name of each field?

Time:09-10

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?

CodePudding user response:

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))
  • Related