I have a Jinja template with a list of dictionaries. Order matters. I'd like to reduce the list or lookup values based on the keys/values of the dictionaries. Here's an example:
{%
set ordered_dicts = [
{
'id': 'foo',
'name': 'My name is Foo'
},
{
'id': 'bar',
'name': 'My name is Bar'
}
]
%}
If I have a variable some_id = 'foo'
, how do I get 'My name is Foo'
out of ordered_dicts
in my Jinja template?
I tried select()
and selectattr()
but couldn't figure them out based on the documentation. Here's what I tried:
{{ ordered_dicts|selectattr("id", "foo") }}
That outputs:
<generator object _select_or_reject at 0x10748d870>
I don't think I'm understanding the use of select()
and selectattr()
properly.
Do I need to iterate over the list and do the lookup manually?
Update:
As codegeek and gipi pointed out, I need to do something like this with the generator:
{{ ordered_dicts|selectattr("id", "foo")|list }}
The resulting error: TemplateRuntimeError: no test named 'foo'
, which clarifies how selectattr()
works. The second argument has to be one of the builtin tests. As far as I can tell, none of these tests will let me check whether the value associated with a key matches another value. Here's what I'd like to do:
{{ ordered_dicts|selectattr("id", "sameas", "foo")|list }}
But that doesn't work, since the sameas
test checks whether two objects are really the same object in memory, not whether two strings/numbers are equivalent.
So is it possible to pick an item based on a key/value comparison test?
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 leverages Jinja2 as its template engine. You are obviously free to use a different template engine, but you still have to install Jinja2 to run Flask itself. This requirement is necessary to enable rich extensions.
I've just backported equalto
like this:
app.jinja_env.tests['equalto'] = lambda value, other : value == other
After that this example from 2.8 docs works:
{{ users|selectattr("email", "equalto", "[email protected]") }}
Update: Flask has a decorator for registering tests, slightly cleaner syntax: http://flask.pocoo.org/docs/api/#flask.Flask.template_test
For people who don't have selectattr (e.g. you're stuck with Jinja2.6), and don't want to make yet another custom filter, these 2 lines will solve your problem real quick.
{% set selection = [] %}
{% for x in biglist if x.criteria == 'pickme' %}{% do selection.append(x) %}{% 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