为什么Django模板语言不允许像[0] [1]这样的东西?

时间:2012-03-08 06:11:35

标签: python django

当我尝试以Django模板格式访问列表中的元组时,我发现我无法使用a[ 0 ][ 1 ]访问该元组,而是必须使用a.0.1

假设a类似于

a = [
    ( 'a', 'apple' ),
    ( 'b', 'bee'   ),
]

为什么Django模板语言不支持a[ 0 ][ 1 ]?在普通的Python编程中,a.0.1会给你一个语法错误。

3 个答案:

答案 0 :(得分:4)

the template API上的Django文档很好地解释了这一点:

  

点在模板渲染中具有特殊含义。变量名中的点表示查找。具体来说,当模板系统遇到变量名中的点时,它会按以下顺序尝试以下查找:

     
      
  • 字典查找。示例:foo["bar"]
  •   
  • 属性查找。示例:foo.bar
  •   
  • 列表索引查找。示例:foo[bar]
  •   
     

模板系统使用第一种有效的查找类型。这是短路逻辑。以下是一些例子:

>>> from django.template import Context, Template
>>> t = Template("My name is {{ person.first_name }}.")
>>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
>>> t.render(Context(d))
"My name is Joe."

>>> class PersonClass: pass
>>> p = PersonClass()
>>> p.first_name = "Ron"
>>> p.last_name = "Nasty"
>>> t.render(Context({"person": p}))
"My name is Ron."

>>> t = Template("The first stooge in the list is {{ stooges.0 }}.")
>>> c = Context({"stooges": ["Larry", "Curly", "Moe"]})
>>> t.render(c)
"The first stooge in the list is Larry."

Variable._resolve_lookup in django.templates.base似乎是对此负责的函数,并没有太大变化since the oldest revision I can find

答案 1 :(得分:3)

您可以在django book

中找到有关此内容的一些信息
  

本章的开头应该解释为什么它以这种方式工作:   在上一章中,您可能已经注意到我们在示例视图中返回文本的方式有些特殊。也就是说,HTML直接在我们的Python代码中进行了硬编码,如下所示:

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
  

虽然这种方法很方便用于解释视图的工作方式,但在视图中直接对HTML进行硬编码并不是一个好主意。原因如下:

     
      
  • 对页面设计的任何更改都需要更改Python代码。站点的设计往往比基础Python代码更频繁地更改,因此如果设计可以更改而不需要修改Python代码将会很方便。
  •   
  • 编写Python代码和设计HTML是两个不同的学科,大多数专业的Web开发环境将这些职责分散在不同的人(甚至是不同的部门)之间。不应要求设计人员和HTML / CSS编码人员编辑Python代码以完成工作。
  •   
  • 如果程序员可以处理Python代码并且设计人员可以同时处理模板,而不是一个人等待另一个人完成编辑包含Python和HTML的单个文件,那么效率最高。
  •   
     

由于这些原因,将页面设计与Python代码本身分开会更清晰,更易于维护。我们可以使用Django的模板系统来完成这个,我们将在本章中讨论它。

     

...

     

点查找可以这样概括:当模板系统遇到变量名中的点时,它会按以下顺序尝试以下查找:

     
      
  • 字典查找(例如,foo [“bar”])
  •   
  • 属性查找(例如,foo.bar)1
  •   
  • 方法调用(例如,foo.bar())
  •   
  • 列表索引查找(例如,foo [2])
  •   
     

系统使用第一种有效的查找类型。这是短路逻辑。

答案 2 :(得分:2)

我之所以说django模板语言不能以XYZ方式访问上下文数据,是因为通常在这一点上你在模板方面做的太多而不是你的视图。

他们的模板引擎的设计决策似乎比其他一些更轻松,可以让您更直接地访问数据。但理想情况下,您可以在传递之前格式化上下文。

您还可以创建自己的模板过滤器,以执行更多自定义数据处理。

特定于您的问题,使用点表示法访问子成员是尝试多种方法来解析成员的django模板方法。它以特定顺序尝试字典键,属性等。你只需使用点符号即可。