Итерации ForLoop как индекс списка в шаблоне Django - PullRequest
3 голосов
/ 19 января 2012

Я создаю веб-страницу django, но, похоже, наткнулся на загадку, так как не могу понять, как использовать текущую итерацию цикла for (в шаблоне) для нескольких списков:

        {% for num in loopRange %}
    <tr>
        {% for num2 in subRange %}
        <td>{% cycle list1 list2 list3 list4 %}</td>
        {% endfor %}
    </tr>
    {% endfor %}

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

У меня есть несколько списков, которые по своему содержанию похожи, каждый список представляет собой столбец в строке. Итак, если бы это был Python, а я объединял строки, это было бы так:

for i in xrange(5):
    string = list1[i] + list2[i] + list3[i] + list 4[i]

Так что в основном это. Я передаю каждый список в качестве контекста в дополнение к двум xranges (loopRange и Subrange в первом примере), мне нужно пять строк (каждый список имеет пять членов) и четыре столбца (четыре списка).

РЕДАКТИРОВАТЬ: я полагаю, что в nuthshell я хочу ссылаться на список индексов как foo [bar], сделано в django как foo.bar, однако bar, очевидно, не может быть целым числом итеративный диапазон, передаваемый как содержимое

Спасибо!

Ответы [ 3 ]

3 голосов
/ 20 января 2012

Я бы сказал, что наилучшим подходом будет работа с данными в представлении перед передачей их в шаблон.

Например, встроенная функция zip может использоваться для создания списка строк.на основе списков, содержащих столбцы:

rows = zip(list1, list2, list3, list4)

После этого шаблон может перебирать строки по одной и обращаться к столбцам, используя доступ к индексу, если необходимо:

{% for row in rows %}
  {{row.0}} {{row.1}} {{row.2}} {{row.3}}
{% endfor %}
1 голос
/ 20 января 2012

Вы можете просто создать простой фильтр для возврата элемента из списка:

@register.filter
def get_item(row, i):
    try:
        return row[i]
    except IndexError:
        return ''

Тогда:

{{ list1|get_item:num2 }}
0 голосов
/ 20 января 2012

Если вы действительно хотите по какой-то причине сделать это в самих шаблонах, вы также можете написать пользовательский тег шаблона , который сделает это за вас:

#app/templatetags/zip.py
from django import template

register = template.Library()

class Zipper(template.Node):
    def __init__(self, format_string, var_name):
        self.format_string = format_string
        self.var_name = var_name
    def render(self, context):
        zippables = [context[tok] for tok in self.format_string.split()]
        import pdb; pdb.set_trace()
        context[self.var_name] = zip(*zippables)
        return ''

import re

@register.tag(name="zip")
def do_zip(parser, token):
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("%r tag requires arguments" % token.contents.split()[0])
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError("%r tag had invalid arguments" % tag_name)
    format_string, var_name = m.groups()
    return Zipper(format_string, var_name)

Примечание : этот синтаксис станет намного проще в Django 1.4 из-за добавления assignment_tag.

Затем просто используйте его так:

{%load zip%}

{% zip list1 list2 list3 list4 as list_of_rows %}

Затем вы можете использовать list_of_rows где угодно в этом блоке, в том числе внутри двух вложенных циклов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...