I'd like to use a variable as an key in a dictionary in a Django template. I can't for the life of me figure out how to do it. If I have a product with a name or ID field, and ratings dictionary with indices of the product IDs, I'd like to be able to say:
{% for product in product_list %}
<h1>{{ ratings.product.id }}</h1>
{% endfor %}
In python this would be accomplished with a simple
ratings[product.id]
But I can't make it work in the templates. I've tried using with... no dice. Ideas?
Create a template tag like this (in yourproject/templatetags):
@register.filter
def keyvalue(dict, key):
return dict[key]
Usage:
{{dictionary|keyvalue:key_variable}}
You need to prepare your data beforehand, in this case you should pass list of two-tuples to your template:
{% for product, rating in product_list %}
<h1>{{ product.name }}</h1><p>{{ rating }}</p>
{% endfor %}
items
on the dictionary that's already in the context -- {% for product, rating in product_list.items %}
will work.
Building on eviltnan's answer, his filter will raise an exception if key
isn't a key of dict
.
Filters should never raise exceptions, but should fail gracefully. This is a more robust/complete answer:
@register.filter
def keyvalue(dict, key):
try:
return dict[key]
except KeyError:
return ''
Basically, this would do the same as dict.get(key, '')
in Python code, and could also be written that way if you don't want to include the try/except block, although it is more explicit.
There is a very dirty solution:
<div>We need d[{{ k }}]</div>
<div>So here it is:
{% for key, value in d.items %}
{% if k == key %}
{{ value }}
{% endif %}
{% endfor %}
</div>
{{dictionary|keyvalue:key_variable|keyvalue:another_key}}
?logic
in templates and encourage putting it in the view