用于访问变量属性的Django点查找语法

时间:2015-09-24 17:38:58

标签: django

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

模板系统使用点查找语法来访问变量属性。在{{question.question_text}}的示例中,首先Django对对象问题进行字典查找。如果失败了,它会尝试进行属性查找 - 在这种情况下可以正常工作。如果属性查找失败,它将尝试列表索引查找。

字典,属性和列表索引查找有什么区别?

3 个答案:

答案 0 :(得分:6)

Django模板中的点查找:

当Django模板系统遇到变量名{{foo.bar}}中的点时,它会按以下顺序尝试查找:

  

模板系统使用第一种有效的查找类型。它的   短路逻辑。

<强> 1。字典查找

在字典查找中,它将尝试执行查找,假定foo为字典,bar为该字典中的键。

foo["bar"] # perform dictionary lookup   

<强> 2。属性查找。

当字典查找失败时,它会执行属性查找,即尝试访问bar中的foo属性。

foo.bar # perform attribute lookup   

第3。列表索引查找。

当属性查找失败时,它将尝试执行列表索引查找,即尝试访问bar中的foo索引。

foo[bar] # perform index lookup   

来自official docs的示例:

>>> from django.template import Context, Template
>>> t = Template("My name is {{ person.first_name }}.")

# Dictionary lookup
>>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
>>> t.render(Context(d))
"My name is Joe."

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

# List-Index lookup
>>> 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."

答案 1 :(得分:0)

来自Django documentation

Dictionary lookup. Example: foo["bar"]
Attribute lookup. Example: foo.bar
List-index lookup. Example: foo[bar]

答案 2 :(得分:0)

之间的区别是:

  1. 字典:
  2. Django的模板语言试图查看你正在使用的东西是否是一个字典,它试图查找属性,好像该对象是一个字典数据结构。

    1. 属性
    2. 如果这不起作用,Django的模板语言将尝试通过将其视为对象的属性来获取该数据(这也可以是调用对象的方法,就像你有{{ {1}})

      1. 列表索引
      2. 如果这不起作用,模板渲染器将尝试通过尝试访问该索引来查看它是否正在使用列表。例如,如果您有一个列表(如评估的查询集),您可以使用question.is_published()来获取列表中的第一个问题。

        我认为你真的在问:

        根据您的背景,使用模板语言起初可能很奇怪。就像我在comment中提到的那样,您可以遍历关系(即,在您要求数据注入模板的表格之间),而不会将其显式传递到视图的上下文数据中。也就是说,你当然可以滥用这种权力,在遍历许多关系时应该谨慎,因为这会导致额外的查找。

        为了更好地了解它是如何工作的,你应该花一些时间在shell中(我喜欢使用django-extension的shell_plus)来玩你的模型的API,看看如何访问关系(通过外键,多对多和一对一的关系)。同样,这确实需要额外的查找(这可以用来缓解select_related和prefetch_related)。