在Jinja2中检查数组是否为空

72

我需要检查变量textsindex.html中是否已定义。

如果该变量已定义并且不为空,则应该渲染循环。否则,我想显示错误信息{{error}}

基本上这是PHP中的操作。

if (isset($texts) && !empty($texts)) {
    for () { ... }
}
else {
    print $error;
}

index.html

{% for text in texts %} 
    <div>{{error}}</div>
    <div class="post">
        <div class="post-title">{{text.subject}}</div>
        <pre class="post-content">{{text.content}}</pre>
    </div>
{% endfor %}

我该如何在jinja2中表示这个?

10个回答

73

我认为最好的方法是结合使用defined()检查和查看数组长度,通过length()函数实现:

{% if texts is defined and texts|length > 0 %}
    ...
{% endif %}

14
texts | length > 0 等同于 texts -- 在布尔测试中,空列表会被评估为 false - Davor Cubranic

57

要测试存在性(“定义性”),请使用is defined

要测试一个非空列表的存在,请将列表本身用作条件。

虽然它似乎不适用于您的示例,但是这种空值检查形式在如果你需要除了循环之外的其他东西时很有用。

一个人工的例子可能是

{% if (texts is defined) and texts %}
    The first text is {{ texts[0] }}
{% else %}
    Error!
{% endif %}

30

请查看Jinja2文档中的defined()函数:http://jinja.pocoo.org/docs/templates/#defined

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

这个是否清晰明了?在你的情况下,它可能看起来像这样:

{% if texts is defined %}
    {% for text in texts %} 
        <div>{{ error }}</div>
        <div class="post">
            <div class="post-title">{{ text.subject }}</div>
            <pre class="post-content">{{ text.content }}</pre>
        </div>
    {% endfor %}
{% else %}
    Error!
{% endif %}

80
根据原问题,这个例子漏掉了定义为空的数组的边缘情况,这也应该是一个错误。请留意。 - Andrew
1
@Andrew,你知道如何解决这个边缘情况吗? - Patrick Mutuku
5
可以这样翻译:处理空但有定义的数组的方式是使用{% if texts %}。 - yeaske

13

文档中所述,您也可以这样写:

{% for text in texts %}
    <div class="post">
        <div class="post-title">{{text.subject}}</div>
        <pre class="post-content">{{text.content}}</pre>
    </div>
{% else %}
    <div>{{ error }}</div>
{% endfor %}

它处理了 texts 未定义和 texts 为空的两种情况。


8
这是一个干净简洁的解决方案,对我非常有效!
{% if texts is defined and texts[0] is defined %}
    ...
{% endif %}

3

texts 可能会被定义,但只包含一个空字符串元素;例如:

texts = ['']

在这种情况下,测试texts是否定义将产生一个真结果,因此您应该测试第一个元素:
{% if texts[0] != '' %}
    ..code here..
{% endif %}

你可能还想结合 |length 过滤器来确保它只有一个元素。


1
这对我很有帮助,尤其是在使用UPS API时。如果父对象中只有一个对象,则子对象仅为一个对象;但是,如果有多个子对象,则为对象数组。
{% if texts[0] %}
    ..code here..
{% endif %}

0
我们可以通过编写以下jinja代码来检查数组是否为空。 其中content2是在py文件中定义的数组。@app.route("/<name>") def home(name): return render_template("index.html", content=name, content2=[])
{% if content2 %}
<div>
    <h2>Array elements are available</h2>
    {% for con2 in content2 %}
        <p> {{con2}} </p>
    {% endfor %}
</div>
{% endif %}

谢谢


0
这个对我有效(但是如果它为空的话,我会确保返回一个空数组 [] 而不是 None)。
{% if array  %}

   <table class="table">
       ...
   </table>

{% endif %}

0
这是我在我的Django应用程序中使用的可行方法:
我需要将一个查询集作为上下文传递到HTML模板中,并且仅在查询集具有值时显示该块。
查询集:
events = Event.objects.filter(schedule_end__gte=date.today()).order_by('-created_at')

将上下文字典传递如下:

{ "events" : events }

HTML模板

{% if events %}
  <h3>Upcoming Events</h3>
  <ul>
    {% for event in events %}
    <li><h4>{{ event.title }}</h4></li>
    {% endfor %}
  </ul>
{% endif %}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接