Умный способ "прерывания" циклов 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))]}

Я хочу иметь таблицу следующего вида: enter image description here

где каждая строка начинается с названия магазина, а затем используется один столбец для каждого товара. Если в магазине более 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)],
    ],
}
Вернуться на верх