Python Django 3.x template tags, галерея изображений, работа с объектами, тегами

Пытаюсь разметить галерею для вебсайта. Дело в том, что при выводе циклом for объектов модели с базы данных (queryset'а) каждые четыре выведеных элемента нужно заключить в <div class="column">, что у меня сделать не получаеться ?‍♂️

Вот, собственно, сам вывод элементов на экран:

{% for i in photos %}
   <img src="{{ i.image.url }}" alt="">
{% endfor %}

Нужно достичь вот такого результата:

<div class="column">
   <img src="1.jpg">
   <img src="2.jpg">
   <img src="3.jpg">
   <img src="4.jpg">
</div>
<div class="column">
   <img src="5.jpg">
   <img src="6.jpg">
   <img src="7.jpg">
   <img src="8.jpg">
</div>


Ответы (2 шт):

Автор решения: Andrey Maslov

попробуй использовать {% cycle %}. он последовательно выводит элементы из списка предоставленных значений, когда элементы заканчиваются начинает заново https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#cycle

<div class="column">
{% for i in photos %}
  {% cycle '' '' '' '' '</div>' %} 
  {% cycle '' '' '' '' '<div class="column">' %}
   <img src="{{ i.image.url }}" alt="">
{% endfor %}
</div>
→ Ссылка
Автор решения: Sergey S.

Как вариант, вы можете использовать {{ forloop }}

Не уверен, что это самое рациональное решение, но я представляю это себе примерно так:

{% for i in photos %}
   {% if forloop.first or forloop.counter % 4 == 0 %}<div class="column">{% endif %}

   <img src="{{ i.image.url }}" alt="">

   {% if forloop.last or forloop.counter % 4 == 0 %}</div>{% endif %}
{% endfor %}

Соответсвенно, каждую 4 итерацию цикла, Django подставит необходимые вам <div></div>, а также в начале и конце итерации цикла, что убережет вас от ошибки, когда картинок в queryset на последних итерациях не хватит для подстановки </div>

Пожалуйста, проверьте возможность использования знака целочисленного деления % внутри тега шаблона. Не уверен, что Django разрешит его. Если нет, то используйте библиотеку django-mathfilters. Тогда ваш шаблон будет выглядеть так:

{% load mathfilters %}
...
{% for i in photos %}
   {% if forloop.first or forloop.counter|intdiv:4 == 0 %}<div class="column">{% endif %}

   <img src="{{ i.image.url }}" alt="">

   {% if forloop.last or forloop.counter|intdiv:4 == 0 %}</div>{% endif %}
{% endfor %}

Прочитайте подробнее в официальной документации

→ Ссылка