在 Jinja2 / Werkzeug 中渲染 python 字典

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19141073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 12:58:50  来源:igfitidea点击:

Rendering a python dict in Jinja2 / Werkzeug

pythonwerkzeugjinja2

提问by user2839288

I'm playing with a url shortener (basing it on the Shortly demo app from Werkzeug).

我正在使用 url 缩短器(基于 Werkzeug 的 Shortly 演示应用程序)。

I have a dict like this -

我有一个这样的字典 -

    ('1', {'target': 'http://10.58.48.103:5000/', 'clicks': '1'})
    ('3', {'target': 'http://slash.org', 'clicks': '4'})
    ('2', {'target': 'http://10.58.48.58:5000/', 'clicks': '1'})
    ('5', {'target': 'http://de.com/a', 'clicks': '0'})

which is returned in url_list and used by render_template

在 url_list 中返回并由 render_template 使用

def on_list_urls(self, request):
    url_list = self.get_urls()
    return self.render_template('list_urls.html',
        url_list = url_list
    )

the template list_urls is pretty simple -

模板 list_urls 非常简单 -

    {% extends "layout.html" %}
    {% block title %}List URLs{% endblock %}
    {% block body %}
      <h2>List URLs</h2>
      <ul id="items">
      {% for item in url_list %}
        <li>{{ item }}</li>
      {% endfor %}
      </ul>

    {% endblock %}

Thing is, I can't seem to access the items in the dict.

问题是,我似乎无法访问 dict 中的项目。

The line

线

<li>{{ item }}</li>

is where I'm focussing attention. As above, I get a list of the keys in the dict.

是我集中注意力的地方。如上所述,我得到了字典中的键列表。

<li>{{ item["target"] }}</li>

returns nothing. None of the {{ user.url }}">{{ user.username }} type stuff in the docs seems to work.

什么都不返回。文档中的 {{ user.url }}">{{ user.username }} 类型的东西似乎都不起作用。

Ideas please? Newbie - be gentle. Thanks.

请问有什么想法吗?新手——要温柔。谢谢。

Update

更新

Thanks for the responses.

感谢您的回复。

Ewan's answer works, but uses a list of dicts. I want to pass a dict and render that (because I want a non-integer index of items). Does Jinja do that?

Ewan 的答案有效,但使用了字典列表。我想传递一个字典并呈现它(因为我想要一个非整数的项目索引)。Jinja会这样做吗?

Also - I mis-represented url_list. It's more like this -

另外 - 我错误地表示了 url_list。更像是这样——

{'a': {'target': 'http://testing.com/test', 'clicks': '0'}, 
'1': {'target': 'http://10.58.48.103:5000/', 'clicks': '1'}, 
'3': {'target': 'http://slash.org', 'clicks': '4'}, 
'2': {'target': 'http://10.58.48.58:5000/', 'clicks': '1'}}

Further experimentation - passing a dict produces an error about a list object.

进一步的实验 - 传递一个 dict 会产生一个关于列表对象的错误。

   {% for key in url_list.iteritems() %}

    UndefinedError: 'list object' has no attribute 'iteritems'

Thanks again.

再次感谢。

Still baffled by why it thought I was passing a list but got it working now.

仍然对为什么它认为我正在传递一个列表但现在让它工作感到困惑。

{% for key, value in url_list.iteritems() %}
    <li>{{ key }} - {{ value["target"] }} - {{ value["clicks"] }}</li>

prints out everything. Many thanks.

打印出所有内容。非常感谢。

采纳答案by Ewan

Your url_listshould look like this:

url_list应该是这样的:

url_list = [{'target': 'http://10.58.48.103:5000/', 'clicks': '1'}, 
            {'target': 'http://slash.org', 'clicks': '4'},
            {'target': 'http://10.58.48.58:5000/', 'clicks': '1'},
            {'target': 'http://de.com/a', 'clicks': '0'}]

Then using:

然后使用:

<li>{{ item["target"] }}</li> 

in your template will work.

在您的模板中将起作用。

Edit 1:

编辑1:

Your template think you're passing a list in, so are you sure you're passing in your original dict and not my above list?

您的模板认为您正在传递一个列表,所以您确定您传递的是原始字典而不是我上面的列表吗?

Also you need to access both a keyand a valuein your dictionary (when you're passing a dictionary rather than a list):

您还需要访问字典中的akey和 a value(当您传递字典而不是列表时):

Python 2.7

蟒蛇 2.7

{% for key, value in url_list.iteritems() %}
    <li>{{ value["target"] }}</li> 
{% endfor %}

Python 3

蟒蛇 3

{% for key, value in url_list.items() %}
    <li>{{ value["target"] }}</li> 
{% endfor %}

回答by Federico Ressi

Please note that dict.items()method is exists in both Python 2 and Python 3. But the method gives no warranties about the order items contained in dictionary are being iterated. This is why it could make more sense for this example to use a list of dictionaries instead of a dictionary of dictionaries like you said above.

请注意该dict.items()方法在 Python 2 和 Python 3 中都存在。但该方法不保证字典中包含的订单项正在被迭代。这就是为什么在这个例子中使用字典列表而不是像上面所说的字典字典更有意义的原因。

回答by coder.in.me

One approach is to cleanly separate processing logic from the HTML. Thus, put HTML in a separate file, such as, top.reddit.html. But content within the HTML is dynamic since it's pulled from Reddit. So we use Jinja2 as the templating engine. This implies that top.reddit.htmlis just the template but not the final content to be served.

一种方法是将处理逻辑与 HTML 完全分开。因此,将 HTML 放在一个单独的文件中,例如top.reddit.html. 但是 HTML 中的内容是动态的,因为它是从 Reddit 中提取的。所以我们使用 Jinja2 作为模板引擎。这意味着这top.reddit.html只是模板,而不是要提供的最终内容。

top.reddit.html (showing only the dynamic rows here for brevity):

top.reddit.html(为简洁起见,此处仅显示动态行):

{% for item in data %}
<tr>
  <td width="0%">&nbsp;</td>
  <td>{{item["date"]}}, {{item["title"]}}<br>{{item["teaser"]}}</td>
  <td width="0%">&nbsp;</td>
</tr>
{% endfor %}

Python code to render the template (tested with Python 3.5.6, Jinja2 2.10):

渲染模板的 Python 代码(使用 Python 3.5.6、Jinja2 2.10 测试):

import jinja2

# For illustration: list of dict
top_posts = [
    {'date': '06 Jun, 11:40AM', 'title': 'Title 1 goes here',  'teaser': 'One blah blah blah...'},
    {'date': '05 Jun, 04:50PM', 'title': 'Title 2 goes here',  'teaser': 'Two blah blah blah...'},
    {'date': '05 Jun, 09:60AM', 'title': 'Title 3 goes here',  'teaser': 'Three blah blah blah...'}
]

loader = jinja2.FileSystemLoader(searchpath="./")
jenv = jinja2.Environment(loader=loader)
template = jenv.get_template('top.reddit.html')
htmlout = template.render(data=top_posts)
print(htmlout)