[Django模板系统]方法调用与无效变量处理

来源:互联网 发布:网络重置怎么弄 编辑:程序博客网 时间:2024/06/10 02:20

        注:以下内容转载自 现代魔法学院 网站的 方法调用与无效变量处理 一文,仅供学习使用。

       Python的列表是从0开始索引。第一项的索引是0,第二项的是1,依此类推。

       句点查找规则可概括为:当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:

  • 字典类型查找 (比如 foo["bar"] )
  • 属性查找 (比如 foo.bar )
  • 方法调用 (比如 foo.bar() )
  • 列表类型索引查找 (比如 foo[bar] )

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

       句点查找可以多级深度嵌套。例如在下面这个例子中 {{ person.name.upper }} 会转换成字典类型查找(person['name'])然后是方法调用(upper()):

>>> from django.template import Template, Context>>> person = {'name': 'Sally', 'age': '43'}>>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')>>> c = Context({'person': person})>>> t.render(c)u'SALLY is 43 years old.'

       方法调用行为

       方法调用比其他类型的查找略为复杂一点。以下是一些注意事项:

       在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个 silent_variable_failure 属性并且值为 True ,否则的话它将被传播。如果异常被传播,模板里的指定变量会被置为空字符串,比如:

>>> t = Template("My name is {{ person.first_name }}.")>>> class PersonClass3:...     def first_name(self):...         raise AssertionError, "foo">>> p = PersonClass3()>>> t.render(Context({"person": p}))Traceback (most recent call last):...AssertionError: foo>>> class SilentAssertionError(AssertionError):...     silent_variable_failure = True>>> class PersonClass4:...     def first_name(self):...         raise SilentAssertionError>>> p = PersonClass4()>>> t.render(Context({"person": p}))u'My name is .'

       仅在方法无需传入参数时,其调用才有效。否则,系统将会转移到下一个查找类型(列表索引查找)。

       显然,有些方法是有副作用的,好的情况下允许模板系统访问它们可能只是干件蠢事,坏的情况下甚至会引发安全漏洞。

       例如,你的一个 BankAccount 对象有一个 delete() 方法。如果某个模板中包含了像 {{ account.delete }} 这样的标签,其中 “account” 又是BankAccount 的一个实例,请注意在这个模板载入时,account 对象将被删除。

       要防止这样的事情发生,必须设置该方法的 alters_data 函数属性:

def delete(self):    # Delete the accountdelete.alters_data = True

       模板系统不会执行任何以该方式进行标记的方法。接上面的例子,如果模板文件里包含了 {{ account.delete }},对象又具有 delete() 方法,而且 delete() 有 alters_data=True 这个属性,那么在模板载入时,delete()方法将不会被执行。它将静静地错误退出。

       无效变量的处理

       默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串,不做任何事情来表示失败。 例如:

>>> from django.template import Template, Context>>> t = Template('Your name is {{ name }}.')>>> t.render(Context())u'Your name is .'>>> t.render(Context({'var': 'hello'}))u'Your name is .'>>> t.render(Context({'NAME': 'hello'}))u'Your name is .'>>> t.render(Context({'Name': 'hello'}))u'Your name is .'

       系统静悄悄地表示失败,而不是引发一个异常,因为这通常是人为错误造成的。这种情况下,因为变量名有错误的状况或名称, 所有的查询都会失败。现实世界中,对于一个web站点来说,如果仅仅因为一个小的模板语法错误而造成无法访问,这是不可接受的。

0 0
原创粉丝点击