Bootstrap Table не отправляет значения выбранных флажков в POST-запросе в приложении Django

Я использую Bootstrap Table (https://bootstrap-table.com/) для отображения списка товаров в приложении Django. Я хочу, чтобы пользователь выбрал несколько товаров и нажал кнопку для отправки. Использование 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-запросе правильно отправляются идентификаторы выбранных товаров, но при включенной строке идентификаторы не отправляются вообще. Bootstrap Table требует атрибут data-toggle="table" для инициализации таблицы, поэтому без него форматирование невозможно.

Это request.body с data-toggle="table" включительно:
<QueryDict: {'csrfmiddlewaretoken': ['fOma6gtvG2ETw1hrVYMdIuSUWuE1RA2jpX2Tae7ntipMPGX4yKNYEGgkHD0Jcuco'], 'btSelectItem': ['on', 'on']}>

Это без него:
<QueryDict: {'csrfmiddlewaretoken': ['Si6UyiTZ4yAJNYKKQ9FtA8dk0gNPGTPp2rMDCgxRROlC6DqntVGewkBKLp9x1NZu'], 'product_checkboxes': ['43004', '43006']}>

Буду очень признателен за любые идеи о том, как я могу использовать фреймворк Bootstrap Table с его форматированием и виджетами, но при этом иметь возможность использовать флажки для сбора данных о продукте.

Вы не можете полагаться на свой HTML, потому что он динамически заменяется BootstrapTable.

Поэтому вам нужно использовать его API для получения значений. Самый простой способ - добавить на страницу скрипт, который будет получать значения из таблицы и назначать их на какой-нибудь (скрытый) элемент формы.

Затем - на стороне 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 template:

<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 будет списком объектов. Каждый объект имеет значения, которые соответствуют столбцам

Вернуться на верх