Bootstrap Table 未在 Django 应用的 POST 请求中发送选定的复选框值

Bootstrap Table not sending selected checkbox values in POST request in Django app

我正在使用 Bootstrap Table (https://bootstrap-table.com/) 在 Django 应用程序中显示产品列表。我希望用户 select 一些产品并单击按钮提交。使用 Bootstrap Table 似乎可以防止在 POST 请求中发送选中的复选框。

views.py

class ProductProcessView(View):
    def post(self, request):
        products = request.POST.getlist('product_checkboxes')
        # process the chosen products
        return redirect('product-list')

html 模板

<form method="post">
    {% csrf_token %}
    <table class="table-striped"
           data-toggle="table"
    >
        <thead>
        <tr>
            <th data-field="product_id" data-checkbox="true"></th>
            <th data-field="product">Product</th>
        </tr>
        </thead>
        {% for product in product_list %}
            <tr>
                <td><input type="checkbox" name="product_checkboxes" value="{{ product.id }}"></td>
                <td>{{ product.short_name }}</td>
            </tr>
        {% endfor %}
    </table>
    <button onclick="location.href='{% url 'process-products' %}'">Select Products</button>
</form>

如果我删除 data-toggle="table" 行,这会在 POST 请求中正确发送 selected 产品 ID,但如果包含该行,它根本不会发送任何 ID。 Bootstrap Table 需要 data-toggle="table" 属性来初始化 table 所以没有它就没有格式。

这是包含 data-toggle="table"request.body
<QueryDict: {'csrfmiddlewaretoken': ['fOma6gtvG2ETw1hrVYMdIuSUWuE1RA2jpX2Tae7ntipMPGX4yKNYEGgkHD0Jcuco'], 'btSelectItem': ['on', 'on']}>

这是没有它的:
<QueryDict: {'csrfmiddlewaretoken': ['Si6UyiTZ4yAJNYKKQ9FtA8dk0gNPGTPp2rMDCgxRROlC6DqntVGewkBKLp9x1NZu'], 'product_checkboxes': ['43004', '43006']}>

对于如何使用 Bootstrap Table 框架及其格式和小部件的任何想法,我将不胜感激,但仍然能够使用复选框来收集产品数据。

您不能依赖您的 HTML,因为它已被 BootstrapTable 动态替换。

因此您需要使用其 API 来检索值。最简单的方法是将脚本添加到页面,该脚本将从 table 获取值并分配给表单中的某些(隐藏)元素。

然后 - 在 Python 端,您将读取此字段并处理数据。

查看示例(使用 JQuery 但可以转换为纯 JS):

<script>
    $(document).ready(function () {
        $('#product-form').on('submit', function () {
            const table = $('#products').bootstrapTable('getSelections')
            $('#checkboxes').val(JSON.stringify(table))
        })
    })
</script>

对模板的一些更正:

  1. 将 ID 添加到表单
  2. 将产品 ID 作为隐藏列包含在内
  3. 添加将通过表单传递内容的隐藏元素

html 模板:

<form method="post" id="product-form">
    {% csrf_token %}
    <table id="products" class="table-striped" data-toggle="table">
        <thead>
        <tr>
            <th data-field="product_check" data-checkbox="true"></th>
            <th data-field="product_id" data-visible="false">ID</th>
            <th data-field="product">Product</th>
        </tr>
        </thead>
        <input id="checkboxes" name="product_checkboxes" style="display: none">
        {% for product in product_list %}
            <tr>
                <td><input type="checkbox" data-id="{{ product.id }}" value="{{ product.id }}"></td>
                <td>{{ product.id }}</td>
                <td>{{ product.short_name }}</td>
            </tr>
        {% endfor %}
    </table>
    <button id="select-products" onclick="location.href='{% url 'process-products' %}'">Select Products</button>
</form>

最后 - 在 views.py 中获取数据:

def post(self, request):
    products = json.loads(request.POST.get('product_checkboxes'))
    # process the chosen products
    return redirect('product-list')

请注意,在本例中 products 将是一个对象列表。每个对象都有对应于列的值