64

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?

CaptainThrowup
  • 919
  • 1
  • 7
  • 15
  • possible duplicate of [how to access dictionary element in django template?](http://stackoverflow.com/questions/1275735/how-to-access-dictionary-element-in-django-template) – Anto Feb 17 '14 at 15:31

4 Answers4

103

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

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

Usage:

{{dictionary|keyvalue:key_variable}}
Thorin Schiffer
  • 2,818
  • 4
  • 25
  • 34
23

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 %}
cji
  • 6,635
  • 2
  • 20
  • 16
  • Thanks cji! I was trying to avoid another object, but it doesn't really matter... it's all cached anyway. – CaptainThrowup May 24 '10 at 03:57
  • 3
    You don't need to prep the data in the view, you can achieve the same thing by calling `items` on the dictionary that's already in the context -- `{% for product, rating in product_list.items %}` will work. – jhrr Feb 24 '17 at 20:36
15

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>
podshumok
  • 1,649
  • 16
  • 20
15

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.

Patrick
  • 2,769
  • 2
  • 25
  • 29
  • 17
    instead of dict[key] you just use the built-in python dictionary get method. e.g.: return dict.get(key, '') – user772401 Sep 29 '14 at 01:33
  • 2
    You should also catch a potential TypeError. Parameter "dict" is not guaranteed to be a Python dict. – jrief Jun 11 '18 at 10:18