使用烧瓶从 HTML table 中删除单个 SQLAlchemy 行

Delete individual SQLAlchemy row from an HTML table with flask

我创建了一个 HTML table,其中列出了来自 SQLAlchemy table 的许多行。 table 是使用 jinja2 模板循环创建的:

{% for single_merchant in merchants %}
        <tr>
            <td>{{single_merchant.id}}</td>
            <td><button type="button" class="btn btn-sm btn-outline-danger">Delete</button>
        </tr>

每一行都有一个“删除”按钮。我想弄清楚如何分配删除按钮来删除特定的 SQLalchemy 行。我尝试将按钮创建为一个名为 delete_form 的单独烧瓶形式,并向 button 添加一个 id="{{single_merchant.id}} 属性,如下所示:

{% for single_merchant in merchants %}
            <tr>
                <td>{{single_merchant.id}}</td>
                <form method="post">
                {{ delete_form.hidden_tag() }}
                <td>{{ delete_form.delete(id=single_merchant.id) }}</td>
                </form>
            </tr>

然后在 app.py 中创建了一个 if 语句:

if delete_form.validate_on_submit():

    print(f"merchant to delete ID - {delete_form.delete.id}")

我希望在输出中得到 single_merchant.id 并在 if 语句中使用它从我的 SQLAlchemy table 中删除特定商家,但我却在输出中得到了 [=19] =] 即使在 HTML 文件中 id 属性的值为 1,因为 {{single_merchant.id}} 是 1

有没有办法从 HTML table 中执行 SQLAlchemy 行删除?这是一个粗略的例子,HTML table 应该是这样的:

实现处理删除的路由:

def merch_delete(mid):
    merch = Merchant.query.filter_by(id=mid).first()
    if merch:
        msg_text = 'Merchant %s successfully removed' % str(merch)
        cs.delete(merch)
        cs.commit()
        flash(msg_text)
    return redirect(url_for('merchants_view'))

然后,将以下内容添加到您的 jinja table 中的一列:

<a href="{{ url_for('merch_delete', mid=single_merchant.id) }}"
  onclick="return confirm('Do you want to permanently delete merchant {{ merchant }}?');" title="Delete Merchant">
  <i class="material-icons" style="font-size:16px">delete</i></a>

图标和Js验证步骤可选

您也可以使用您原来的方法,只需在具有删除按钮的表单中添加一个隐藏字段,其中的值可以是您的 ID。您只需明确定义 csrf_token 而不是使用 hidden_tag() 方法。

在您的 WtfForm class object 中定义一个隐藏字段,例如:

class DeleteForm(FlaskForm):
    delete_id = HiddenField("Hidden table row ID")
    delete = SubmitField("Delete")

像这样在您的 HTML Jinja2 模板中渲染它。请注意,我翻转了 <td><form>,这样您的整个 table 数据单元格就是形式

{% for single_merchant in merchants %}
<tr>
    <td>{{single_merchant.id}}</td>
    <td>
        <form method="post">
            {{ delete_form.csrf_token }}
            {{ delete_form.delete_id(value=single_merchant.id) }}
            {{ delete_form.delete(class="btn btn-danger") }}
        </form>
    </td>
</tr>

然后在您的代码中,您可以使用 wtfform validate_on_submit() 轻松检查它,然后使用 SQLAlchemy get() 方法查询从隐藏字段中提取值的 id data属性。

def post(self):
    if self.delete_form.validate_on_submit():
        entry_to_delete = YourSQLAlchemyTableClassObject.query.get(self.delete_form.delete_id.data)
        db.session.delete(entry_to_delete)
        db.session.commit()

如果您想将 entry_to_delete 行与 db.session.delete() 合并,您可以通过使用隐藏字段数据 属性 将查询放入 table调用 delete() 方法。我喜欢将这些部分分开,以防在删除找到的条目之前我需要做任何额外的事情,但这并不重要。

这是我为家人开发的一个应用程序的屏幕截图,它允许我的孩子为我们的迪士尼假期添加建议。我没有像你那样使用很酷的垃圾桶图标,但你明白了。