使用 WTForms 和 Flask 预填充编辑表单

Pre-Populate an edit form with WTForms and Flask

我可以使用 WTForms 和 Flask 向我的数据库添加一个新条目,我也可以编辑,问题是我需要在编辑表单中显示数据库中已经存在的信息。

我有以下代码:

A Class 用于编辑 Post 表单

class editPostForm(Form):
    postTitle = TextField('postTitle', validators.Required()])
    postSubtitle = TextField('postSubtitle', validators.Required()])

编辑路径 Post 模板

@app.route('/editpost/<postId>', methods = ['GET','POST'])
def editpost_page(postId):
try:
    form = editPostForm(form)

    if request.method == "POST" and form.validate():
        postTitle = form.postTitle.data
        postSubtitle = form.postSubtitle.data

        c, conn = connection()

        query = c.execute("SELECT * FROM posts WHERE post_id = (%s)",
                          [noinjection(postId)])

        c.execute("UPDATE posts SET post_title=%s, post_subtitle=%s WHERE post_id = %s",
                     [
                     noinjection(postTitle),
                     noinjection(postSubtitle),
                     noinjection(postId)
                     ])

        conn.commit()

        flash("Post Edited", 'success')

        c.close()
        conn.close()
        gc.collect()

        return redirect(url_for('posts'))

    return render_template("editpost.html", form = form, POST_ID = postId)

except Exception as e:
    return(str(e))

编辑Post模板{jinja}

{% extends "header.html" %}

{% block body %}

<body>
    <div class="container-fluid">
        <br />
        <h4>Edit Post</h4>
        <br />
        {% from "_formhelpers.html" import render_field %}
        <form action="/editpost/{{ POST_ID }}" class="form-horizontal" method="post">
            {% from "_formhelpers.html" import render_field %}
            <form action="/editpost/" method="post">
              <div class="form-group">
                <label for="postTitle">Post Title</label>
                <input type="text" class="form-control" id="postTitle" name="postTitle" placeholder="Post Title" value="{{request.form.postTitle}}">
              </div>
              <div class="form-group">
                <label for="postSubtitle">Post Subtitle</label>
                <input type="text" class="form-control" id="postSubtitle" name="postSubtitle" placeholder="Post Subtitle" value="{{request.form.postSubtitle}}">
              </div>
              <button type="submit" class="btn btn-default">Submit</button>
            </form>
            {% if error %}
                <p class="error"><strong>Error: </strong>{{error}}</p>
            {% endif %}
        </form>
        {% if error %}
            <p class="error"><strong>Error: </strong>{{error}}</p>
        {% endif %}

    </div>
</body>

{% endblock %}

使用以下代码,我在数据库中选择了要更新的 post,但是 editpost 模板没有显示数据库中已有的值和所有字段是空白的。

如何在编辑前预填充表单?

您可以像这样分别填充每个字段:

form = editPostForm(form)
form.postTitle.data = postTitle_from_database
form.postSubtitle.data = postSubtitle_from_database

或者您可以使用 process 方法从给定对象填充表单字段:

process(formdata=None, obj=None, **kwargs)

Take form, object data, and keyword arg input and have the fields process them.

Parameters:

  • formdata – Used to pass data coming from the enduser, usually request.POST or equivalent.
  • obj – If formdata has no data for a field, the form will try to get it from the passed object.
  • **kwargs – If neither formdata or obj contains a value for a field, the form will assign the value of a matching keyword argument to the field, if provided.

Since BaseForm does not take its data at instantiation, you must call this to provide form data to the enclosed fields. Accessing the field’s data before calling process is not recommended.

我能够使用 Python 和 Jinja 从 SQL 数据库中预填充 HTML inputtextarea 字段,如下所示:

1.将数据库中的相关数据存储在变量中:

    name = db.execute("""SELECT name FROM users WHERE id = :id""", id=session["user_id"])

    about = db.execute("""SELECT about FROM users WHERE id = :id""", id=session["user_id"])

2。渲染模板(带render_template函数)并传入相关变量:

return render_template("edit.html", name = name, about = about)

3。通过 jinja 将变量传递给 html inputtextarea 元素。传入的对象索引如下:

对于 input 标签,使用如下值属性:

    <input type="text" class="form-control" name="name" value="{{ name[0]["name"] }}">

对于 textarea 元素:

    <textarea class="form-control" name="about">{{ about[0]["about"] }}</textarea>