Итерация вложенного dict в шаблоне mako
У меня есть следующий дикт:
{"name1":{"text":"my text 1", "status":"my status"}, "name2":{"text":"my text 2", "status":"my status"}}
Используя шаблон Mako, я хочу создать HTML-таблицу. Я попробовал следующее:
Фрагмент Python:
test = {"name1":{"text":"my text 1", "status":"my status"}, "name2":{"text":"my text 2", "status":"my status"}}
mytemplate = Template(filename='template/index.mako')
return mytemplate.render(data=test)
Мако фрагмент:
% for key, val in data.iteritems():
<tr>
<td>${loop.index + 1}</td>
<td>${key}</td>
% for tkey, tval in val.iteritems():
<td>${tkey}</td>
<td>${tval}</td>
% endfor
</tr>
% endfor
Приведенные выше фрагменты вызывают ошибку (объект 'str' не имеет атрибута 'iteritems').
Как правильно перебирать вложенные диктовки?
Спасибо
1 ответ
Это странно сложно сделать. Недавно я пытался сделать что-то очень похожее, нашел этот пост, и мне было грустно видеть, что на него не было никаких ответов.
Вы просили "правильный" способ, и я думаю, что итерации по элементам будут наиболее питонским способом; но я также не смог заставить это работать. Я смог заставить работать рекурсивный парсер (с дополнительным бонусом, который будет обрабатывать n уровней вложенности).
Я получил это на работу:
from mako.template import Template
template = '''
${handleLevel(pages)}
<%def name="handleLevel(level, depth=0)">
% if isinstance(level, dict):
% for item in level:
% if isinstance(level[item], dict):
<!-- print this item for this level -->
${handleLevel(level[item], depth+1)}
<!-- end this level (close div or anything that should contain next level -->
% else:
<!-- handle bottom level (linke, or div, etc.) -->
${item}
<!-- close any elements for bottom level not already closed -->
% endif
% endfor
% endif
</%def>
'''
nested = {
'A': {'B': 'C'},
'D': 'E',
}
page = Template(template).render(pages=nested)
print(page)
Если вы знаете, что у вас когда-либо будет только один уровень вложенности, вы можете просто выполнить цикл for, например:
from __future__ import print_function
from mako.template import Template
template = '''
% for key in data:
<tr>
<td>${loop.index + 1}</td>
<td>${key}</td>
% for secondKey in data[key]:
<td>${secondKey}</td>
<td>${data[key][secondKey]}</td>
% endfor
</tr>
% endfor
'''
test = {"name1":{"text":"my text 1", "status":"my status"}, "name2":{"text":"my text 2", "status":"my status"}}
page = Template(template).render(data=test)
print(page)
(проверено в Python3 и 2)
Хотя теперь, когда я немного поиграл с этим, ваш код отлично работает для меня в Python 2.7.15 и mako версии 1.0.7 .,,