Альтернативная раскраска строк в шаблоне Django с более чем одним набором строк


шаблоны Django предлагают встроенный тег cycle для чередования нескольких значений в разных точках шаблона (или для цикла в шаблоне), но этот тег не сбрасывается, когда он доступен в области за пределами cycleопределение s. Т. е., если у вас есть два или более списков в вашем шаблоне, строки всех из которых вы хотели бы использовать некоторые определения css odd и even, первая строка списка будет забрать, где последний остановился, а не с новой итерации из выбор (odd и even)

например, в следующем коде, если первый блог имеет нечетное число записей, то первая запись во втором блоге будет начинаться как even, когда я хочу, чтобы это началось с odd.

{% for blog in blogs %}
  {% for entry in blog.entries %}
    <div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}">
      {{entry.text}}
    </div>
  {% endfor %}
{% endfor %}

я пытался избежать этого путем исправления с resetcycle тег предложили здесь:

Django билет: тег цикла должен сбросить после того, как он выходит за рамки

безрезультатно. (Код не работает для мне.)

я также попытался переместить мой внутренний цикл в пользовательский тег, но это также не сработало, возможно, потому, что цикл компиляции/рендеринга перемещает цикл обратно во внешний цикл? (Независимо от того, почему это не работает для меня.)

как я могу выполнить эту простую задачу!? Я бы предпочел не создавать структуру данных, на мой взгляд, с этой предварительно скомпилированной информацией; это кажется ненужным. Спасибо заранее.

7 58

7 ответов:

самый простой обходной путь (до тех пор, пока патч resetcycle не будет исправлен и применен)-использовать встроенный фильтр "divisibleby" с forloop.счетчик:

{% for entry in blog.entries %}
  <div class="{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}" id="{{ entry.id }}">
    {{ entry.text }}
  </div>
{% endfor %}

немного более многословен, но не трудно понять, и он отлично работает.

https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#cycle

{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2' %}">
        ...
    </tr>
{% endfor %}

вы можете использовать tagged cycle и resetcycle (новый в Django 1.11) звонки (от https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-resetcycle ):

{% for blog in blogs %}
  {% cycle 'odd' 'even' as rowcolors silent %}
  {% resetcycle rowcolors %}
  {% for entry in blog.entries %}
    {% cycle rowcolors %}
    <div class="{{ rowcolors }}" id="{{entry.id}}">
      {{ entry.text }}
    </div>
  {% endfor %}
{% endfor %}

Я в конечном итоге делаю это, с forloop.counter0-он отлично работает!

{% for product in products %}

    {% if forloop.counter0|divisibleby:4 %}<div class="clear"></div>{% endif %}

    <div class="product {% if forloop.counter0|divisibleby:4 %}col{% else %}col20{% endif    %}">
        Lorem Ipsum is simply dummy text
    </div>

{% endfor %}

самый простой ответ может быть: "сдавайтесь и используйте jQuery."Если это приемлемо, это, вероятно, проще, чем бороться с шаблонами Django над чем-то таким простым.

и Система Шаблонов Jinja2

я отказался от языка шаблонов django, он очень ограничен в том, что вы можете с ним сделать. Jinja2 использует тот же синтаксис, что и шаблон django, но добавляет много улучшений над ним.

EDIT / NOTE ( Я знаю, что это звучит как большой переключатель для всего лишь незначительной проблемы, но на самом деле я уверен, что вы всегда будете бороться с системой шаблонов по умолчанию в django, так что это действительно стоит и я считаю, это сделает вас более продуктивным в долгосрочной перспективе. )

вы можете узнать эта статья написана автором, хотя это технически, он упоминает проблему тега {%cycle %} в django.

Jinja не имеет тега цикла, у него есть метод цикла в цикле:

{% for user in users %}
    <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
{% endfor %}

основным преимуществом Jinja2 является то, что он позволяет использовать логику для презентации, поэтому, если у вас есть список изображений, вы можете поместить их в таблицу, потому что вы можно начать новую строку внутри таблицы каждые N элементов, см., Вы можете сделать, например:

{% if loop.index is divisibleby(5) %}   
     </tr>
     {% if not loop.last %}
     <tr>
     {% endif %}
{% endif %}

вы также можете использовать математические выражения:

{% if x > 10 %}

и вы можете получить доступ к своим функциям python напрямую (но некоторые настройки необходимы, чтобы указать, какие функции должны быть представлены для шаблона)

{% for item in normal_python_function_that_returns_a_query_or_a_list() %}

даже набор переменных ..

{% set variable_name = function_that_returns_an_object_or_something() %} 

есть способ сделать это на стороне сервера с итератором, который не сохраняет одновременную копию всех записей:

import itertools
return render_to_response('template.html',
  {
    "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)),
  })