I'm playing with a url shortener (basing it on the Shortly demo app from Werkzeug).
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
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 -
{% 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.
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.
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?
Also - I mis-represented url_list. It's more like this -
{'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.
{% 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.
To iterate through a list of dictionaries in Jinja template with Python Flask, we use a for loop. to create the parent_list list of dicts. in our Jinja2 template to render the parent_list items in a for loop.
Flask in Action When inserting Python code into the HTML file, we wrap it in {% %} so Flask knows to differentiate it from normal HTML code. To print out the contents of the dict, we can use a for loop. The idea of the for loop stays the same, it's just spread out across multiple lines and wrapped in HTML.
Jinja2 works with Python 2.6. x, 2.7. x and >= 3.3. If you are using Python 3.2 you can use an older release of Jinja2 (2.6) as support for Python 3.2 was dropped in Jinja2 version 2.7.
Jinja2 being a templating language has no need for wide choice of loop types so we only get for loop. For loops start with {% for my_item in my_collection %} and end with {% endfor %} . This is very similar to how you'd loop over an iterable in Python.
Your url_list
should look like this:
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.
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 key
and a value
in your dictionary (when you're passing a dictionary rather than a list):
Python 2.7
{% for key, value in url_list.iteritems() %} <li>{{ value["target"] }}</li> {% endfor %}
Python 3
{% for key, value in url_list.items() %} <li>{{ value["target"] }}</li> {% endfor %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With