views:

136

answers:

3

Is there a way to do something like the following in Django templates?

   {% for hop in hops%}
    <tr>  
      <td>{{ hop.name }}</td>
      <td>{{ hop.mass }}</td>  
      <td>{{ hop."boil time" }}</td>
 </tr>
  {% endfor %}

The hop."boil time" doesn't work. The simple solution is rename the key boil_time, but I'm interested in alternatives.

+1  A: 

The best way to get at it is to sneak the property name into another variable, like so:

{% for key, value in hop.items %}
    {% ifequal key 'boil time' %}
        {{ value }}
    {% endifequal %}
{% endfor %}

In Django 0.96 (the version used by Google AppEngine) the templating language doesn't support tuple expansion, so it's a bit uglier:

{% for hop in hops %}
    <tr>
        <td>{{ hop.name }}</td>
        <td>{{ hop.mass }}</td>
        <td>
            {% for item in hop.items %}
                {% ifequal item.0 'boil time' %}
                    {{ item.1 }}
                {% endifequal %}
            {% endfor %}
        </td>
    </tr>
{% endfor %}

So, taking your code, we end up with:

{% for hop in hops %}
    <tr>
        <td>{{ hop.name }}</td>
        <td>{{ hop.mass }}</td>
        <td>
            {% for key, value in hop.items %}
                {% ifequal key 'boil time' %}
                    {{ value }}
                {% endifequal %}
            {% endfor %}
        </td>
    </tr>
{% endfor %}

In Django 0.96 (the version on Google AppEnginge), this becomes:

{% for hop in hops %}
    <tr>
        <td>{{ hop.name }}</td>
        <td>{{ hop.mass }}</td>
        <td>
            {% for item in hop.items %}
                {% ifequal item.0 'boil time' %}
                    {{ item.1 }}
                {% endifequal %}
            {% endfor %}
        </td>
    </tr>
{% endfor %}

There's even a wordier way to get at it, using the regroup tag:

{% regroup hop.items by 'boil time' as bt %}
    {% for item in bt %}
        {% if forloop.first %}
            {% for item2 in item.list %}
                {% for item3 in item2 %}
                    {% if not forloop.first %}
                        {{ item3 }}
                    {% endif %}
                {% endfor %}
            {% endfor %}
        {% endif %}
{% endfor %}
Douglas Mayle
Django template language does not allow this. The template language equivalent for `hop['boil time']` would be `hop.boil time` (which I think is the problem he is getting at).
T. Stone
Here's a reference for the comment I made above showing that the `.` notation covers indexes... http://docs.djangoproject.com/en/dev/ref/templates/api/#rendering-a-context
T. Stone
I appreciate the effort to write out all of the code, but for some reason, it doesn't seem to work for me, event with copy and paste. I can't get iteration over a dictionary to print any keys or values, even without an ifequals.
Dan Hook
Dan, I actually tested the code on an instance I was running and it worked i both cases... The only thing that I could think of is a problem with items. Try just doing a {{ hop.items }} to see what comes out. If the dictionary had the items method overriden, that could cause issues (e.g. hop has an 'items' property, then try hop.iteritems)
Douglas Mayle
The google appengine uses Django 0.96, which doesn't support the key,value in dict.items syntax. http://groups.google.com/group/django-users/browse_thread/thread/9160209ccfa94a30/492e6882bbc5e6e4?#492e6882bbc5e6e4
Dan Hook
You can actually use Django 1.0 (or 1.1) on Google App Engine by specifying the version in your main.py: http://code.google.com/appengine/docs/python/tools/libraries.html#Django
tomlog
+1  A: 

You could use a get filter from djangosnippets: http://www.djangosnippets.org/snippets/1412/

(Renaming the key is probably better...)

Ned Batchelder
I'll give that a shot and let you know how it goes.
Dan Hook
Man, I've been doing too much Ruby. My inclination is to monkeypatch `dict` to transform underscores into spaces...
jleedev
I probably should have mentioned I'm using django templates in the google appengine, not a full django app. There does not appear to be an easy way to add filters.
Dan Hook
A: 

For django 0.96, which is what the Google Appengine uses for templates, the following works:

{% for hop in recipe.get_hops %}
    {% for item in hop.items %}
          {% ifequal item.0 'boil time' %}
              <p>{{ item.1 }}</p>
          {% endifequal %}
        {% endfor %}   
  {% endfor %}

item.0 is the key and item.1 is the value. Link.

Dan Hook