Умный способ "прерывания" циклов for при итерации
Я хочу итерировать список элементов и поместить их в таблицу, но я хочу, чтобы таблица обрывалась после x элементов. Я использую bootstrap5 для форматирования таблицы.
Я хочу отобразить следующий дикт в виде таблицы:
{'store_6': [ProductData(id=1516004, stat=0), ProductData(id=1516028, stat=2)]}
{'store_3': [ProductData(id=590418, stat=5), ProductData(id=590422, stat=1), ProductData(id=590423, stat=1), ProductData(id=590424, stat=2), ProductData(id=590425, stat=0), ProductData(id=590427, stat=4), ProductData(id=590432, stat=0)), ProductData(id=1590418, stat=0), ProductData(id=1590422, stat=0), ProductData(id=1590423, stat=0), ProductData(id=1590424, stat=0), ProductData(id=1590425, stat=0), ProductData(id=1590427, stat=2), ProductData(id=1590432, stat=0)), ProductData(id=1690418, stat=0), ProductData(id=1690422, stat=0), ProductData(id=1690423, stat=1), ProductData(id=1690424, stat=3), ProductData(id=1560425, stat=0), ProductData(id=1690427, stat=5), ProductData(id=1690432, stat=0))]}
Я хочу иметь таблицу следующего вида:

где каждая строка начинается с названия магазина, а затем используется один столбец для каждого товара. Если в магазине более 10 товаров, первый столбец пустой. Не может быть более 32 товаров.
У меня есть рабочее решение, но оно выглядит ... причудливо:
{% for store_number, products in all_store_data.items %}
{% for device in products %}
{% if forloop.first %}
<tr>
<td class="col-sm-2">{{ store_number }}</td>
{% endif %}
{% if forloop.counter == 11 or forloop.counter == 21 or forloop.counter == 31 %}
<tr>
<td class="col-sm-2"></td>
{% endif %}
<td class="col-sm-1">
{{ device.id }}
</td>
{% if forloop.last %}
{% for add_row in forloop.counter|fill_until_10 %}
<td class="col-sm-1"></td>
{% endfor %}
{% endif %}
{% if forloop.counter|modulo:10 %}
</tr>
{% endif %}
{% endfor %}
{% endfor %}
с двумя маленькими вспомогательными фильтрами:
@register.filter
def modulo(num, val):
return num % val == 0
@register.filter
def fill_until_10(counter):
return range(10 - counter % 10)
Моя проблема сейчас в том, что я не думаю, что код в шаблоне "легко читается" - у кого-нибудь есть идея, как лучше подойти к этому?
Я хотел избежать mark_safe магии и поэтому старался избегать дополнительных фильтров шаблона.
Я бы обрабатывал данные в Django view так, чтобы каждый магазин содержал список списков (один список для каждой строки). Тогда рендеринг был бы намного проще для логики процессора Django Template.
eg.
data = {
"store_6": [[ProductData(id=1516004, stat=0), ProductData(id=1516028, stat=2)]],
"store_3": [
[
ProductData(id=590418, stat=5),
ProductData(id=590422, stat=1),
ProductData(id=590423, stat=1),
ProductData(id=590424, stat=2),
ProductData(id=590425, stat=0),
ProductData(id=590427, stat=4),
ProductData(id=590432, stat=0),
ProductData(id=1590418, stat=0),
ProductData(id=1590422, stat=0),
ProductData(id=1590423, stat=0),
],
[
ProductData(id=1590424, stat=0),
ProductData(id=1590425, stat=0),
ProductData(id=1590427, stat=2),
ProductData(id=1590432, stat=0),
ProductData(id=1690418, stat=0),
ProductData(id=1690422, stat=0),
ProductData(id=1690423, stat=1),
ProductData(id=1690424, stat=3),
ProductData(id=1560425, stat=0),
ProductData(id=1690427, stat=5),
],
[ProductData(id=1690432, stat=0)],
],
}