使用Flask和WTForms,如何创建一个带有输入框的表格?

1 投票
2 回答
10112 浏览
提问于 2025-04-18 13:51

我在理解这个问题上有点困难,文档似乎也没什么帮助。

我需要生成一个表格,行数会变化,但不是动态的(我在生成页面之前就知道需要多少行)。

为了简单起见,假设我们有一个页面,用整数给 n 个考试打分。

我尝试了这个:

表单部分。

class InputInteger(Form):
    grade = IntegerField('Grade')

视图部分

@decorator..
def grade():
    form = InputInteger()
    names = student_list

    return render_template("grade.html", form=form, names=names)

模板部分

<table>
    <tr>
        <th>Name</th>
        <th>Grade</th>
    </tr>
    {% for name in names %}
    <tr>
        <td>
            {{name}}
        </td>
        <td>
            {{form.grade}}
        </td>
    </tr>
</table>

但是我该怎么读取输入的值呢?

我怎么知道哪个分数是属于谁的呢?

我有点困惑,我读过关于 FieldList(FormField(IntegerField)) 的内容,但那不就是一个包含整数的字段列表吗?

那表格小部件(Table Widget)又是什么?我需要用到它吗?

请帮帮我。

2 个回答

1

你说得差不多对。把你的表格放在一个 HTML 表单里面,然后在一个函数里处理,这样你就可以获取到你的输入字段。

这里有个例子:

<form action="/grade">
    <table>
        <tr>
            <th>Name</th>
            <th>Grade</th>
        </tr>
        {% for name in names %}
        <tr>
            <td>{{name}}</td>
            <td><input id='{{name}}' value='{{ form.grade }}'></td>
        </tr>
    </table>
</form>

还有你的 Flask 函数:

@app.route('/grade', methods=['GET', 'POST'])
def grade():
    if request.method == 'POST':
      return 'Form posted.'

当你把表单提交到你的函数时,可以通过这种方式访问你的输入字段:request.form['inputfieldname'],然后你就可以进行后续操作了。希望我的解释能让你明白。

6

对于现在看到这个内容的朋友,提问者的想法是对的,确实应该考虑到 FieldListFormField。下面是一个解决方案:

forms.py 文件:

class GradeForm(FlaskForm):
    student = IntegerField('Student ID')
    grade = IntegerField('Grade')
    delete = BooleanField('Delete')

class GradeFormSet(FlaskForm):
    gradeset = FieldList(FormField(GradeForm), min_entries=0)

view.py 文件:

def grade():
    # create a dict of student IDs and their initial grades (or None for now)
    init_merits = [dict(student=s.id, grade=None) for s in myStudentTable.query.all()]
    gradeform = GradeFormSet(gradeset=init_merits)
    if form.validate_on_submit():
        ...
        # meritforms.data['gradeset'] contains a list of dictionary values for further processing
        # check 'delete' == True to handle deletion of that student from your table
        ...
    return render_template('template.html', form=gradeform)

模板:

<table>
{% for merit in form.gradeset %}
    <tr>
        <td>{{ merit.placing(readonly=true) }} {{ merit.csrf_token }} {{ merit.hidden_tag() }}</td>
        <td>{{ merit.grade }}</td>
        <td>{{ merit.delete }}</td>
    </tr>
{% endfor %}
</table>

<input type="submit" name="finish" value="Save">
<input type="submit" name="cancel" value="Cancel">

撰写回答