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