0

in Django I want to display some entries in a dictionary of lists.

My context is:

keys = ['coins', 'colors']
dict = {'colors':['red', 'blue'],
        'animals':['dog','cat','bird'],
        'coins':['penny','nickel','dime','quarter'] } 

Template code:

<ul>{% for k in keys %}
    <li>{{ k }}, {{ dict.k|length }}: [{% for v in dict.k %} {{ v }}, {% endfor %}]
{% endfor %}</ul>

I want to see:

* coins,4: [penny, nickel, dime, quarter,]
* colors,2: [red, blue,]

But what I actually see is keys but no values:

* coins,0: []
* colors,0: []

Note: I also tried dict.{{k}} instead of dict.k, but as expected that just gave a parse error in template rendering. I'll get rid of the trailing comma with forloop.last after getting the basic list working.

What is the secret sauce for displaying selected values from a dictionary of lists?

The question django template and dictionary of lists displays an entire dictionary, but my requirement is to display only a few entries from a potentially very large dictionary.

Community
  • 1
  • 1
Dave
  • 3,834
  • 2
  • 29
  • 44
  • 2
    Essentially Django makes it unnecessarily painful to use `dict` in templates and access in any normal way. You are right that the `dict.k` lookup is not working because it is looking for a literal `k` attribute rather than the value of your template variable. For this use case I would recommend writing your own custom tag or filter to do the work. – Two-Bit Alchemist Sep 09 '15 at 17:32

2 Answers2

2

The problem (as you suspected) is that dict.k is evaluated to dict['k'] where 'k' is not a valid key in the dictionary. Try instead to iterate each item pair using dict.items and only display the results for the keys you're concerned with:

<ul>{% for k, v in dict.items %}
        {% if k in keys %}
            <li>
            {{ k }}, {{ v|length }}: [{% for val in v %} {{ val }},{% endfor %}]
           </li>
        {% endif %}
    {% endfor %}
</ul>
Chad S.
  • 6,252
  • 15
  • 25
Gocht
  • 9,924
  • 3
  • 42
  • 81
  • Is it `items` or `iteritems`? – Shang Wang Sep 09 '15 at 17:35
  • @ShangWang items, my bad. – Gocht Sep 09 '15 at 17:38
  • Yes, thanks for confirming my fears. I was hoping to avoid processing an entire dictionary just to display a few entries, but I guess Django templates aren't that pythonic. Looks like I'll have to rewrite views.py to pass in a bunch of subset dicts to the template. – Dave Sep 09 '15 at 17:56
  • The alternative is to write a simple template filter to do the dynamic lookup: it's three lines of code, see an example in [this answer](http://stackoverflow.com/a/8000091/104349) – Daniel Roseman Sep 09 '15 at 18:15
0
<ul>
    {% for k, v in dict.items %} # instead of iterating keys, iterate dict
        {% if k in keys %} # if key found in keys
            <li>
                {{ k }}, {{ v|length }}: [{% for val in v %} {{ val }},{% endfor %}]
            </li>
        {% endif %}
    {% endfor %}
</ul>
taesu
  • 4,482
  • 4
  • 23
  • 41