Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested dot lookups in Django templates

According to The Django Book, Django's templating system supports nested dot lookups:

Dot lookups can be nested multiple levels deep. For instance, the following example uses {{ person.name.upper }}, which translates into a dictionary lookup (person['name']), then a method call (upper()): '{{ person.name.upper }} is {{ person.age }} years old.'

Are there goblins with this approach not widely covered in the documentation? I am having problems with nested dot lookups -- here's a minimal example:

views.py:

test = [{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}]
ndx = 'bar'
t = loader.get_template('meh.html')
c = Context({'test': test,
             'ndx': ndx,})
return HttpResponse(t.render(c))

meh.html template:

<pre>
   {{ test }}
   {{ test.0 }}
   {{ test.0.ndx }}
</pre>

Resulting HTML:

<pre>
[{'foo': [1, 2, 3], 'bar': [4, 5, 6]}, {'baz': [7, 8, 9]}]
 {'foo': [1, 2, 3], 'bar': [4, 5, 6]}

</pre>

The nested lookup of a dictionary key within a list element returns nothing, when I expect [4, 5, 6].

J.J.

like image 778
J.J. Avatar asked Dec 18 '09 16:12

J.J.


People also ask

What does {% %} mean in Django?

{% %} and {{ }} are part of Django templating language. They are used to pass the variables from views to template. {% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.

What does {{ name }} mean in Django templates?

8. What does {{ name }} this mean in Django Templates? {{ name }} will be the output. It will be displayed as name in HTML. The name will be replaced with values of Python variable.

What is DTL in Django?

Django Template Language (DTL) is the primary way to generate output from a Django application. You can include DTL tags inside any HTML webpage. The basic DTL tag you can include in an HTML webpage is: 1. {% Tag %}

When {% extends %} is used for inheriting a template?

extends tag is used for inheritance of templates in django. One needs to repeat the same code again and again. Using extends we can inherit templates as well as variables.


1 Answers

I think the problem is that you are expecting ndx to be evaluated when that simply never happens. Have you tried this:

{{ test.0.bar }}

I think that will do what you're looking for.

Are there goblins with this approach...?

Sort of, but they aren't the ones you're talking about, and I don't think it's because of nesting, or at least, it doesn't get worse after you get one level deep. What I mean by this is that all lookup parameters are literals. There's no way to change that. So while you might be able to develop custom template tags and pass them literals or variables to evaluate, you're really out of luck if you want to directly access some member of a variable based on the evaluated value of another value. (You could possibly write a template tag for this, but it won't work in all desired situations and is possibly more complicated than it's worth.)

For whatever it's worth, this looks like a pretty intentional facet of the templating language. I invite you to consider how the accessor should know whether {{ foo.bar }} should be read as foo[bar] or foo['bar']. It doesn't seem possible to make a meaningful judgment without complicating the syntax and that's something that django's template design is adamant about avoiding.

like image 190
David Berger Avatar answered Sep 25 '22 09:09

David Berger