2

I am trying to retrieve the value of a dictionary key and display that on the page in a Django template:

{% for dictkey in keys %}
    <p> {{ mydict.dictkey }} </p>
{% endfor %}

(let's say 'keys' and 'mydict' have been passed into the template in the Context)

Django renders the page but without the dictionary contents ("Invalid template variable")

I assume the problem is that it is trying to do mydict['dictkey'] instead of mydict[actual key IN the variable dictkey]? How does one "escape" this behavior?

Thanks!

UPDATE: Based on the answers received, I need to add that I'm actually looking specifically for how to achieve a key lookup inside a for loop. This is more representative of my actual code:

{% for key, value in mydict1.items %}
    <p> {{ mydict2.key }} </p>
{% endfor %}

Basically, I have two dictionaries that share the same keys, so I can't do the items() trick for the second one.

mindthief
  • 12,755
  • 14
  • 57
  • 61
  • The less fancy logic in the template the better. Try and prepare the data in an easily templatable fashion before passing it to be rendered. – kevpie Dec 06 '10 at 04:38

3 Answers3

4

See this answer to a (possibly duplicate) related question.

It creates a custom filter that, when applied to a dictionary with a key as it's argument, does the lookup on the dictionary using the key and returns the result.

Code:

@register.filter
def lookup(d, key):
    if key not in d:
        return None
    return d[key]

Usage:

{% for dictkey in dict1.keys %}
    <p> {{ dict2|lookup:dictkey }} </p>
{% endfor %}

Registering the filter is covered in the documentation.

I find it sad that this sort of thing isn't built in.

Community
  • 1
  • 1
Cameron
  • 96,106
  • 25
  • 196
  • 225
  • @Cameron: nice, that looks like it'll do what I want! Thanks! But yea shouldn't have to use a custom filter like this for something so simple. At least I now know about custom filters :) – mindthief Dec 06 '10 at 04:22
  • @mindthief: Glad to have helped. If the limitations intentionally imposed in Django templates start to get to you too much, you might want to consider switching to another templating language -- [Jinja2](http://jinja.pocoo.org/) is excellent and has similar syntax but many more features (including dictionary lookups!) – Cameron Dec 06 '10 at 04:26
  • Thanks for the tips! So I'm having a little trouble getting the custom filter to work atm -- I put it in a file myextras.py which is located in the same folder as the django project. Added {% load myextras %} at the top of the template.html file, and the file contains the code you provided (@register filter def lookup...). I also added 'from django import template' and 'register = template.Library()' to this file to see if that would work, but I still get the error message "myextras is not a valid tag library: Template library myextras not found, tried django.templatetags.myextras". Any ideas? – mindthief Dec 06 '10 at 05:19
  • 1
    @mindthief: Sounds like Django can't find myextras (your code seems correct). Is `myextras.py` in the `templatetags` directory? Is there an empty `__init__.py` file in the directory? Make sure your directory is set up exactly as per the [instructions](http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#code-layout) – Cameron Dec 06 '10 at 14:09
  • @Cameron: Yes, that was it! Ugh, I was hesitant to add a new app just to get the filter to work, so I had tried to just put the templatetags/ folder in the main django project folder (didn't have any apps in this project). I figured that it should be able to find it in that folder just the same as if it were in an "installed app", but apparently not. I tried that now and it worked -- that is, I did 'python manage.py startapp extras'. And then copied templatetags/ into that folder, added 'myproj.extras' to INSTALLED_APPS in settings.py, and that did it. Really appreciate the assistance! :) – mindthief Dec 07 '10 at 06:02
  • You could have used `d.get(key)` – Facundo Casco Oct 27 '11 at 19:15
1

From http://docs.djangoproject.com/en/dev/ref/templates/builtins/#for

This can also be useful if you need to access the items in a dictionary. For example, if your context contained a dictionary data, the following would display the keys and values of the dictionary:

{% for key, value in data.items %}
    {{ key }}: {{ value }}
{% endfor %}

The trick is that you need to call dict.items() to get the (key, value) pair.

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
  • I actually did do that, but for another dict. The problem I guess is that I actually have two dictionaries that share the same keys. One of them is in the for loop as: for key, value in myDict1.items:

    {{ myDict2.key }}

    – mindthief Dec 06 '10 at 04:01
1

See the docs: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#for

{% for key, value in data.items %}
    {{ key }}: {{ value }}
{% endfor %}
Adam Vandenberg
  • 19,991
  • 9
  • 54
  • 56