Django 模板中的嵌套点查找

问题描述 投票:0回答:4

根据 The Django Book,Django 的模板系统支持嵌套点查找:

点查找可以嵌套多层。例如,以下示例使用 {{ person.name.upper }},它会转换为字典查找 (person['name']),然后是方法调用 (upper()): '{{ person.name.upper }} 已经 {{ person.age }} 岁了。'

文档中是否有没有广泛介绍这种方法的妖精? 我在嵌套点查找方面遇到问题 - 这是一个最小的示例:

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 模板:

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

生成的 HTML:

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

</pre>

列表元素中字典键的嵌套查找(

test.0.ndx
)不会返回任何内容,但我期望
[4, 5, 6]
。 请注意,
ndx
的计算结果为
bar

python django django-templates
4个回答
10
投票

我认为问题在于,您期望

ndx
得到评估,但实际上这种情况从未发生过。 你试过这个吗:

{{ test.0.bar }}

我认为这将满足您的需求。

有采取这种做法的哥布林吗……?

有点,但它们不是你所说的那些,我不认为这是因为嵌套,或者至少,在你深入一层后,情况不会变得更糟。 我的意思是所有查找参数都是文字。 没有办法改变这一点。 因此,虽然您可能能够开发自定义模板标签并向它们传递要评估的文字或变量,但如果您想根据另一个值的评估值直接访问变量的某些成员,那么您真的很不走运。 (您可以为此编写一个模板标签,但它不会在所有所需的情况下工作,并且可能比它的价值更复杂。)

无论它的价值如何,这看起来都是模板语言的一个非常有意的方面。 我邀请您考虑访问者应该如何知道

{{ foo.bar }}
是否应该读作
foo[bar]
foo['bar']
。 在不使语法复杂化的情况下似乎不可能做出有意义的判断,而这是 django 的模板设计坚决要避免的事情。


4
投票

为了扩展 David 的答案,Django 的模板系统不允许您使用上下文变量的值作为键。 所以,在你的例子中

{{ test.0.ndx }}

实际上是在

"ndx"
上下文变量的第一项中寻找键
test

如果您需要此功能,您需要自己实现它,作为模板过滤器。 此票包含更多信息,包括 Django 开发人员省略此功能背后的推理以及您正在寻找的模板过滤器的示例实现。


1
投票

David 是对的:

ndx
不会被评估以获得密钥,它将被字面上用作密钥。 您可以定义一个新的模板标记来执行您想要的操作,这是一个简单的标记:http://www.djangosnippets.org/snippets/1412/


1
投票

我建议其中之一(我同意大卫对你的问题的解释):

{{ test.0.bar }} # as david mentioned, or

ndx=test[0]['bar'] # in views
{{ ndx }} # in template
© www.soinside.com 2019 - 2024. All rights reserved.