【问题标题】:Recursively find child items and list in jinja在jinja中递归查找子项和列表
【发布时间】:2017-06-29 05:21:51
【问题描述】:

我正在尝试在嵌套列表中显示“注释”。每个笔记都有一个名为parentID 的属性,表示它嵌套在下面的笔记。

目前我正在通过这样做实现单层嵌套:

models.py

class Note(Model):
    title = CharField()
    tags = CharField()
    content = TextField()
    parentID = IntegerField(default=0)

    class Meta:
        database = db

app.py

def getSubnotes(note):
    note_id = note.id
    subnotes = models.Note.select().where(models.Note.parentID == note_id)
    return subnotes

app.jinja_env.globals.update(getSubnotes=getSubnotes)

Index.html

<div class="row">
<div class="medium-12 medium-centered">
  <ul>
    {% for note in notes %}
      {% if note.parentID == 0 %}
      <li><a href="/n/{{note.getHash()}}">{{ note.title }}</a></li>
      <ul>
        {% for subnote in getSubnotes(note) %}
        <li><a href="/n/{{subnote.getHash()}}">{{ subnote.title }}</a></li>
        {% endfor %}
      </ul>
      {% endif %}
    {% endfor %}
  </ul>
</div>

然而,我想递归地找到单个音符的所有子音符并将它们列出来,所以有嵌套的嵌套。

我已经将此视为如何在 jinja 中递归列出的示例(来自 jinja docs):

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>

但是我对.children 的实际含义感到困惑。它是如何引用自己或同一类型的items 的?

我将如何递归地执行此操作,或者是否有更好的方法来实现相同的目标?

非常感谢任何帮助!

【问题讨论】:

    标签: python python-3.x recursion flask jinja2


    【解决方案1】:

    在文档的示例中,我认为 item.children 只是相同类型项目的可迭代。然后{{ loop(item.children) }} 导致当前循环在可迭代的item.children 上执行,创建一个嵌套列表。

    您可以验证这一点:

    import jinja2
    
    templ = """
    {%- for item in items recursive %}
        {{item.name}}
        {%- if item.children %}
            {{- loop(item.children) }}
        {%- endif %}
    {%- endfor %}
    """
    
    items = [{'name': 'Bobby'},
             {'name': 'Jack',
              'children': [
                  {'name': 'Jake'},
                  {'name': 'Jill'}]},
             {'name': 'Babby', 'children': []}]
    
    template = jinja2.Template(templ)
    print(template.render(items=items))
    

    打印出来

    Bobby
    Jack
    Jake
    Jill
    Babby
    

    所以在你的例子中,我认为你应该能够做类似的事情

    <div class="row">
    <div class="medium-12 medium-centered">
      <ul>
        {% for note in notes recursive %}
          {% if note.parentID == 0 %}
          <li><a href="/n/{{note.getHash()}}">{{ note.title }}</a></li>
          <ul>
            {{ loop(getSubnotes(note)) }}
          </ul>
          {% endif %}
        {% endfor %}
      </ul>
    </div>
    

    只要 getSubnotes(note) 在注释没有子注释时返回空。

    【讨论】:

      【解决方案2】:

      在我看来,它更完整(它探索了列表中的列表和字典):

      <dl class="row">
        {% for key, value in json.items() recursive %}
        {% set outer_loop = loop %}
        <dt class="col-3">{{ key }}</dt>
        <dd class="col-9">
        {% if value is string %}
          {{ value }}
        {% elif value is mapping %}
          <dl class="row">
            {{ loop(value.items()) }}
          </dl>
        {% elif value is iterable %}
          <ol>
          {% for item in value %}
            <li>
            {% if item is mapping %}
              <dl class="row">
                {{ outer_loop(item.items()) }}
              </dl>
            {% else %}
              {{ item }}
            {% endif %}
            </li>
          {% endfor %}
          </ol>
        {% else %}
          {{ value }}
        {% endif %}
        </dd>
      {% endfor %}
      </dl>
      

      我想知道是否/如何简化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-03
        • 2014-08-03
        • 2018-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多