Раскраска альтернативных рядов в шаблоне Django с более чем одним набором рядов - PullRequest
58 голосов
/ 20 января 2009

Шаблоны Django предлагают встроенный тег cycle для чередования нескольких значений в разных точках шаблона (или для цикла в шаблоне), но этот тег не сбрасывается при обращении к нему за пределами cycle. определение. Т.е., если у вас есть два или более списков в вашем шаблоне, строки из которых вы хотели бы использовать некоторые определения 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: тег Cycle должен сбрасываться после того, как он выходит из области действия

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

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

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

Ответы [ 7 ]

111 голосов
/ 20 января 2009

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

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

Немного более многословно, но не сложно понять, и это прекрасно работает.

14 голосов
/ 18 июня 2015

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

{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2' %}">
        ...
    </tr>
{% endfor %}
3 голосов
/ 20 декабря 2017

Вы можете использовать помеченные 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 %}
2 голосов
/ 14 апреля 2011

В итоге я делаю это с 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 %}
1 голос
/ 20 января 2009

Откажитесь и используйте Система шаблонов Jinja2

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

РЕДАКТИРОВАТЬ / ПРИМЕЧАНИЕ (Я знаю, это звучит как большой переход для незначительной проблемы, но на самом деле, держу пари, вы всегда будете сражаться со стандартной системой шаблонов в 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() %} 
1 голос
/ 20 января 2009

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

0 голосов
/ 20 января 2009

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

import itertools
return render_to_response('template.html',
  {
    "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)),
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...