Use variable as dictionary key in Django template

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?


Solution 1:

Create a template tag like this (in yourproject/templatetags):

@register.filter
def keyvalue(dict, key):    
    return dict[key]

Usage:

{{dictionary|keyvalue:key_variable}}

Solution 2:

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 %}

Solution 3:

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>

Solution 4:

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.