递归查找子项目并列入jinja

时间:2017-06-29 05:21:51

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

我试图展示"笔记"在嵌套列表中。每个音符都有一个名为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的?

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

非常感谢任何帮助!

2 个答案:

答案 0 :(得分: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)返回空。

答案 1 :(得分:1)

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

<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>

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