Home » Python » how to access dictionary element in django template?

how to access dictionary element in django template?

Posted by: admin November 1, 2017 Leave a comment

Questions:

I have this code in template, which I would like to printout number of votes that each choice got. votes is just dictionary while choices are model object.

{% for choice in choices %}
    {{choice.choice}} - {{votes[choice.id]}} <br />
{% endfor %}

it raises an exception with this message “Could not parse the remainder”

Answers:

To echo / extend upon Jeff’s comment, what I think you should aim for is simply a property in your Choice class that calculates the number of votes associated with that object:

    class Choice(models.Model):
        text = models.CharField(max_length=200) 

        def calculateVotes(self):
            return Vote.objects.filter(choice = self).count()

        votes = property(calculateVotes)

And then in your template, you can do:

    {% for choice in choices %}
            {{choice.choice}} - {{choice.votes}} <br />
    {% endfor %}

The template tag, is IMHO a bit overkill for this solution, but it’s not a terrible solution either. The goal of templates in Django is to insulate you from code in your templates and vice-versa.

I’d try the above method and see what SQL the ORM generates as I’m not sure off the top of my head if it will pre-cache the properties and just create a subselect for the property or if it will iteratively / on-demand run the query to calculate vote count. But if it generates atrocious queries, you could always populate the property in your view with data you’ve collected yourself.

Questions:
Answers:
choices = {'key1':'val1', 'key2':'val2'}

Here’s the template:

<ul>
{% for key, value in choices.items %} 
  <li>{{key}} - {{value}}</li>
 {% endfor %}
</ul>

Basically, .items is a Django keyword that splits a dictionary into a list of (key, value) pairs. This enables iteration over a dictionary in a Django template.

Questions:
Answers:

you can use the dot notation:

Dot lookups can be summarized like
this: when the template system
encounters a dot in a variable name,
it tries the following lookups, in
this order:

  • Dictionary lookup (e.g., foo[“bar”])
  • Attribute lookup (e.g., foo.bar)
  • Method call (e.g., foo.bar())
  • List-index lookup (e.g., foo[2])

The system uses the first lookup type
that works. It’s short-circuit logic.

Questions:
Answers:

You need to find (or define) a ‘get’ template tag, for example, here.

The tag definition:

@register.filter
def hash(h, key):
    return h[key]

And it’s used like:

{% for o in objects %}
  <li>{{ dictionary|hash:o.id }}</li>
{% endfor %}

Questions:
Answers:

Ideally, you would create a method on the choice object that found itself in votes, or create a relationship between the models. A template tag that performed the dictionary lookup would work, too.

Questions:
Answers:

django_template_filter
filter name get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

Questions:
Answers:

Similar to the answer by @russian_spy :

<ul>
{% for choice in choices.items %} 
  <li>{{choice.0}} - {{choice.1}}</li>
{% endfor %}
</ul>

This might be suitable for breaking down more complex dictionaries.