【问题标题】:Flask-WTF FieldList issue: more instances than requiredFlask-WTF FieldList 问题:实例多于要求
【发布时间】:2021-08-26 00:22:10
【问题描述】:

我是使用 Flask 和 html 的新手,但通过研究我发现了多种可能的解决方案,但我仍然遇到错误。

我正在处理一个页面,管理员用户将向已发送请求的新用户提供访问权限。在可能的用户提交他们的请求后,它将被上传到 access_request_table。我在一个表中显示所有应用程序,该表对每一行使用 FieldList,因为整个页面是我唯一的表单。我想这样做,所以我可以从我的 access_request_table 中删除这些行并将它们发送到 users_table,但是,你会看到 FieldList 的长度和行数是不同的。

页面可以正常工作,并以我想要的方式显示,但是,当我手动将数据输入表单并单击提交按钮时,它会向 FieldList 添加比应有的条目更多的条目。我已经尝试了多次和方法让它运行,但它不会正常运行。 例如,这里的表格有 2 行,所以我应该期望我的 FieldList 只有 2 个输入,但它有 4 个。所以如您所见,我无法验证我的表单,也无法打印测试语句。

此处显示表格:example of table rendered

这是我点击提交时的输出:

{  'rows': [
       {'id': '', 'access': 'Yes', 'comment': ''}, 
       {'id': '', 'access': 'No', 'comment': ''}, 
       {'id': None, 'access': '', 'comment': None}, 
       {'id': None, 'access': '', 'comment': None}
   ], 
   'submit': True, 'csrf_token': 'ImFhMDg0YTM3N2YxYWY4OTkwODQwZDY1Y2FhYjNhYWI1ZThjN2MxOTQi.YSbbMQ.OjHsnnYZTjjh308FLuqR6zekMEY'
}

rerender

这是我的forms.py:

class AccessRow(Form):
    # The HiddenField later contains the id of the data record. 
    id = HiddenField('id')
    access = SelectField('access', validators=[DataRequired()], choices=[('','Please Select...'),('Yes','True'),('No','False')], default='',coerce=str)
    comment = StringField('comments')

    # The constructor is overwritten in order to bypass further fields for the csrf token. 
    def __init__(self, csrf_enabled=False, *args, **kwargs):
        super(AccessRow, self).__init__(csrf_enabled=csrf_enabled, *args, **kwargs)

class AccessForm(FlaskForm):
    rows = FieldList(FormField(AccessRow),validators=[Required()])  
    submit = SubmitField('Update')

这是我的 routes.py,目前我将重定向静音以了解所有内容是否已验证且正确。

@app.route("/home/admin", methods=['GET', 'POST'])
def home_admin():
    requests = RequestAccess.query.all()
    form = AccessForm()
    for request in requests:
        form.rows.append_entry()

    if form.is_submitted():   
        print(form.data)

    if form.validate_on_submit():
        print('test')
      #  return redirect(url_for('about'))
    print('rerender')
    return render_template("admin_access_approval.html", title="Admin Access Approval", form=form, requests=requests, range=range(rows))

最后这是我的html:

{% extends "layout.html" %}
{% block content %}
<div id="example_wrapper-2" class="dataTables_wrapper" >
    <form id="basicForm" method="POST" action="" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
        
        <h2 class="h3">Access requests Table</h2>  
        <table id="dataTableExample" class="table table-striped" style="width:100%"> 
            <caption class="sr-only">Employee List</caption>
            <thead>
                <tr><th scope="col">Name</th>
                        <th scope="col">Last name</th>
                        <th scope="col">Work Type</th>
                        <th scope="col">Email</th>
                        <th scope="col">Access</th>
                        <th scope="col">Comments</th>
                        <td></td>
                </tr>
            </thead>
            <tbody>
                {%for row, request, ii in zip(form.rows, requests,range)%}
                    <tr>
                        <td>{{request.name}}</td>
                        <td>{{request.lastname}}</td>
                        <td>{{request.workdesc}}</td>
                        <td>{{request.email}}</td>
                        <td>{{row.access(class="custom-select")}}</td>
                        <td>{{row.comment(class="form-control", value ='')}}</td>
                    </tr>
                {%endfor%}
                <tr>
            </tbody>
        </table>
        <div class="form-group">
            {{ form.submit(class="btn btn-primary mt-2", value = "Submit Changes") }}
        </div>
    </form>
</div>
{%endblock content%}

我一直在尝试很多想法,但我无法实现,非常感谢您的帮助。

谢谢!

【问题讨论】:

    标签: python-3.x flask jinja2 flask-sqlalchemy flask-wtforms


    【解决方案1】:

    您的用户首先访问该页面(GET 请求),逻辑通过home_admin() 并通过for 循环将 2 行附加到表单。这些在页面上呈现。用户点击提交(POST 请求)。这次逻辑通过home_admin() 回溯,表单中已经有 2 行(用户输入的值)。然后它再次到达for 循环并添加 2 个空行,总共 4 个。

    您可以通过在 2 个 if 语句之后移动 for 循环来快速修复。如果要构建其他逻辑,则将不同的 GET/POST 逻辑嵌套在 if request.method == 'GET':elif request.method == 'POST': 中可能更直接。

    【讨论】:

      猜你喜欢
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      相关资源
      最近更新 更多