Python 来自'的分层无序列表;平面';文件夹结构词典

Python 来自'的分层无序列表;平面';文件夹结构词典,python,dictionary,turbogears2,ordereddictionary,genshi,Python,Dictionary,Turbogears2,Ordereddictionary,Genshi,在后端,我从API获得一个文件夹结构。我递归地遍历这个结构以获得所有文件夹。然后,它们都存储在一个“扁平”有序字典中。每个文件夹都存储有一些属性,用于定义结构、父文件夹的id、其子文件夹的数量以及自身是否为子节点 现在,从这个有序的dict中,我试图用Genshi创建一个很好的层次视图,但到目前为止,我得到的最远的是下面的模板。这只会产生两个级别,根级别和下面的一个级别。任何更深的文件夹都将显示在第二层 我试图做到这一点,而不必在数据的初始解析中进行大量的关系检查,以获得文件夹所处的级别。有人有

在后端,我从API获得一个文件夹结构。我递归地遍历这个结构以获得所有文件夹。然后,它们都存储在一个“扁平”有序字典中。每个文件夹都存储有一些属性,用于定义结构、父文件夹的id、其子文件夹的数量以及自身是否为子节点

现在,从这个有序的dict中,我试图用Genshi创建一个很好的层次视图,但到目前为止,我得到的最远的是下面的模板。这只会产生两个级别,根级别和下面的一个级别。任何更深的文件夹都将显示在第二层

我试图做到这一点,而不必在数据的初始解析中进行大量的关系检查,以获得文件夹所处的级别。有人有什么聪明的想法吗

<body>
  <div class="main_content">
    <h1>Catalogue Tree</h1>
    <ul>
      <li py:for="nodeId, nodeProps in nodes.iteritems()">
        <a py:if="nodeProps['SubNode'] == False" href="${tg.url('/node/' + nodeId)}">${nodeProps['Name']}</a>
        <py:if test="nodeProps['SubNode'] == True">
          <ul>
            <a href="${tg.url('/node/' + nodeId)}">${nodeProps['Name']}</a>
          </ul>
        </py:if>
      </li>
    </ul>
  </div>
</body>

目录树

正如我所评论的,您可以使用使用
py:def
指令创建的递归宏来解决问题。以下是我尝试的解决方案(注意,我的系统上没有安装
genshi
,因此这是未经测试的):


  • ${display_nodes(节点[node_id]['SubNodes'])}
  • ${显示节点(根节点)}

    模板的这一部分需要传递两个参数,一个是包含所有节点的
    节点
    字典,另一个是包含所有顶级节点ID的
    根节点
    序列。它创建的结构与您链接到的代码的结构略有不同,因为它在父节点的
  • 标记中包含子节点列表。我不确定这对渲染是否有任何影响,但我认为这样做最正确。

    您的数据节点有父->子链接,还是只有子->父链接?使用前者,您可以定义一个递归模板函数来扩展它们,但是如果您没有一种简单的方法来获取父级的所有子级,那么这将更加困难。在原始api中,xml结构实际上是嵌套的,因此我可以轻松添加父级>子级链接。但我不知道接下来该怎么做。你能详细说明一下吗?我会使用
    py:def
    定义一个“宏”,将链接输出到一个节点,然后,如果节点有子节点,则创建一个嵌套列表并递归调用自身来呈现每个子节点。我的系统中没有
    genshi
    ,因此我无法做出一个我知道有效的答案,但希望这个建议足以让你走上正确的道路。你的建议确实是正确的选择!实际上,我首先将根节点与所有其他节点分开(现在不确定是否有必要这样做),因此我将2个dict传递给模板。然后在模板中,我确实使用了
    py:def
    来生成一个宏,该宏也会调用自身来迭代子节点。这太棒了!谢谢看到代码,也许你可以把它作为一个答案,这样我就可以投你一票,因为你毕竟想出了整个想法!太棒了,谢谢!这甚至更好,效率更高,它显示得更漂亮,也让我在后端更好地清理代码:)解决方案中只有一个小错误,您在
    py:def
    中声明
    node\u id
    ,但在
    for
    循环中使用
    nodes\u id
    。我很高兴这有帮助。我已经修复了
    nodes\u id
    typo(在代码的早期草稿中调用参数
    nodes
    的延迟)。
    <ul py:def="display_nodes(node_ids)">
        <li py:for="node_id in node_ids">
            <a href="${tg.url('/node/' + node_id)}">${nodes[node_id]['Name']}</a>
            <py:if test="nodes[node_id]['SubNodes']">
                 ${display_nodes(nodes[node_id]['SubNodes'])}
            </py:if>
        </li>
    </ul>
    ${display_nodes(root_nodes)}