【问题标题】:Iterate nested dict in mako template在 mako 模板中迭代嵌套的 dict
【发布时间】:2016-12-31 17:50:36
【问题描述】:

我有以下字典:

{"name1":{"text":"my text 1", "status":"my status"}, "name2":{"text":"my text 2", "status":"my status"}}

使用 Mako 模板,我想创建一个 html 表格。我尝试了以下方法:

Python sn-p:

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)

真子sn-p:

% 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

上述sn-ps引发错误('str'对象没有属性'iteritems')。

迭代嵌套字典的正确方法是什么?

谢谢

【问题讨论】:

    标签: python python-2.7 mako


    【解决方案1】:

    很难做到这一点。我最近试图做一些非常相似的事情,发现了这篇文章,很遗憾看到它没有任何答案。

    您要求“正确”的方式,我认为迭代项目将是最 Pythonic 的方式;但我也无法让它发挥作用。我能够让递归解析器工作(额外的好处是这将处理 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 中对我来说可以正常工作。 . .

    【讨论】: