Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering a dictionary in Jinja2

Tags:

python

jinja2

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.

like image 909
user2839288 Avatar asked Oct 02 '13 15:10

user2839288


People also ask

How do you iterate through a dictionary in Jinja2?

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.

How do you print a dictionary in flask?

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.

Does Jinja2 work with Python 3?

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.

How do you write a for loop in Jinja2?

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.


1 Answers

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.

Edit 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 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 %} 
like image 73
Ewan Avatar answered Oct 13 '22 03:10

Ewan