如何使用 jinja 遍历字典中的值列表?

How to iterate over a list of values in a dict using jinja?

我有一个包含值列表的字典,基本上每个键都有 10 个值:

movies = {
'title': ['The Shawshank Redemption', 'The Godfather', ..., 'The Lord of the Rings: The Fellowship of the Ring'],
'year': ['1994', '1972', ..., '2001'],
'poster': ['url', 'url1', ..., 'url9'],
'rating': ['9.2', '9.1', ..., '8.8'],
'votes': ['2467733', '1705796', ..., '1732916']
}

我正在使用它们在 HTML 中动态生成卡片,因此我需要每张卡片的每个键都有一个值。最终我会得到 10 张卡片。这是我的 HTML 和我用 jinja 迭代字典的最新尝试:

{% for movie in movies %}
    {% for key, value in movie.items() %} <!-- This line is raising an error: jinja2.exceptions.UndefinedError: 'str object' has no attribute 'items' -->
        {% for value in key %}
            <div class="col-md-3">
                <div class="card" style="width: 15rem;">
                    <img src="{{ value.poster }}" class="card-img-top" alt="Movie Poster">
                    <div class="card-body">
                      <h5 class="card-title">{{ value.title }}</h5>
                      <p class="card-text">Release year: {{ value.year }}</p>
                    </div>
                    <ul class="list-group list-group-flush">
                      <li class="list-group-item">Rating: {{ value.rating }} - ({{ value.votes }} Votes)</li>
                    </ul>
                    <div class="card-body">
                     <a href="#" class="card-link">More</a>
                    </div>
                </div>
            </div>
         {% endfor %}
     {% endfor %}
 {% endfor %}

Jinja 的语法是什么?

问题不在于语法,而在于您的数据 - 您以错误的方式组织数据。
然后你所有的 for 循环都没有意义。

您有一个包含多个列表的字典,但您应该有一个包含多个字典的列表。

movies = [
    {
        'title': 'The Shawshank Redemption',
        'year': '1994',
        'poster': 'url',
        'rating': '9.2',
        'votes': '2467733'
    },
    {
        'title': 'The Godfather',
        'year': '1972',
        'poster': 'url1',
        'rating': '9.1',
        'votes': '1705796', 
    },
    # ... other movies ...
]

然后您可以使用您的

{% for movie in movies %}
     {{ movie.poster }}
     {{ movie.title }}
     {{ movie.year }}
     {{ movie.rating }} - ({{ movie.votes }}


对于原始数据,您以错误的方式使用了 for 循环。第一个 for-loop {% for movie in movies %}{% for key in movies.keys() %} 一样工作,你得到字符串 "title" 并尝试将它与下一个 for-loop 一起使用 - 这就是你的问题.您必须像 movies.title[n]for n in range(movies.title|length)).

一样使用 index
{% for n in range(movies.title|length)) %}
     {{ movies.poster[n] }}
     {{ movies.title[n] }}
     {{ movies.year[n] }}
     {{ movies.rating[n] }} - ({{ movies.votes[n] }}

编辑:

两个版本的完整工作代码。

from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/')
def index():
    movies = [
        {
            'title': 'The Shawshank Redemption',
            'year': '1994',
            'poster': 'url',
            'rating': '9.2',
            'votes': '2467733'
        },
        {
            'title': 'The Godfather',
            'year': '1972',
            'poster': 'url1',
            'rating': '9.1',
            'votes': '1705796', 
        },
        # ... other movies ...
    ]

    return render_template_string('''
{% for movie in movies %}
<div class="col-md-3">
    <div class="card" style="width: 15rem;">
        <img src="{{ movie.poster }}" class="card-img-top" alt="Movie Poster">
        <div class="card-body">
          <h5 class="card-title">{{ movie.title }}</h5>
          <p class="card-text">Release year: {{ movie.year }}</p>
        </div>
        <ul class="list-group list-group-flush">
          <li class="list-group-item">Rating: {{ movie.rating }} - ({{ movie.votes }} Votes)</li>
        </ul>
        <div class="card-body">
         <a href="#" class="card-link">More</a>
        </div>
    </div>
</div>
{% endfor %}
''', movies=movies)


@app.route('/version2')
def version2():
    
    movies = {
        'title': ['The Shawshank Redemption', 'The Godfather', ..., 'The Lord of the Rings: The Fellowship of the Ring'],
        'year': ['1994', '1972', ..., '2001'],
        'poster': ['url', 'url1', ..., 'url9'],
        'rating': ['9.2', '9.1', ..., '8.8'],
        'votes': ['2467733', '1705796', ..., '1732916']
    }

    return render_template_string('''
{% for n in range(movies.title|length) %}
<div class="col-md-3">
    <div class="card" style="width: 15rem;">
        <img src="{{ movies.poster[n] }}" class="card-img-top" alt="Movie Poster">
        <div class="card-body">
          <h5 class="card-title">{{ movies.title[n] }}</h5>
          <p class="card-text">Release year: {{ movies.year[n] }}</p>
        </div>
        <ul class="list-group list-group-flush">
          <li class="list-group-item">Rating: {{ movies.rating[n] }} - ({{ movies.votes[n] }} Votes)</li>
        </ul>
        <div class="card-body">
         <a href="#" class="card-link">More</a>
        </div>
    </div>
</div>
{% endfor %}
''', movies=movies)

if __name__ == '__main__':
    #app.debug = True 
    app.run()