在Python的Django框架中调用方法和处理无效变量
方法调用行为
方法调用比其他类型的查找略为复杂一点。以下是一些注意事项:
在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个silent_variable_failure属性并且值为True,否则的话它将被传播。如果异常被传播,模板里的指定变量会被置为空字符串,比如:
>>>t=Template("Mynameis{{person.first_name}}.")
>>>classPersonClass3:
...deffirst_name(self):
...raiseAssertionError,"foo"
>>>p=PersonClass3()
>>>t.render(Context({"person":p}))
Traceback(mostrecentcalllast):
...
AssertionError:foo
>>>classSilentAssertionError(AssertionError):
...silent_variable_failure=True
>>>classPersonClass4:
...deffirst_name(self):
...raiseSilentAssertionError
>>>p=PersonClass4()
>>>t.render(Context({"person":p}))
u'Mynameis.'
仅在方法无需传入参数时,其调用才有效。否则,系统将会转移到下一个查找类型(列表索引查找)。
显然,有些方法是有副作用的,好的情况下允许模板系统访问它们可能只是干件蠢事,坏的情况下甚至会引发安全漏洞。
例如,你的一个BankAccount对象有一个delete()方法。如果某个模板中包含了像{{account.delete}}这样的标签,其中``account``又是BankAccount的一个实例,请注意在这个模板载入时,account对象将被删除。
要防止这样的事情发生,必须设置该方法的alters_data函数属性:
defdelete(self): #Deletetheaccount delete.alters_data=True
模板系统不会执行任何以该方式进行标记的方法。接上面的例子,如果模板文件里包含了{{account.delete}},对象又具有delete()方法,而且delete()有alters_data=True这个属性,那么在模板载入时,delete()方法将不会被执行。它将静静地错误退出。
如何处理无效变量
默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串,不做任何事情来表示失败。例如:
>>>fromdjango.templateimportTemplate,Context
>>>t=Template('Yournameis{{name}}.')
>>>t.render(Context())
u'Yournameis.'
>>>t.render(Context({'var':'hello'}))
u'Yournameis.'
>>>t.render(Context({'NAME':'hello'}))
u'Yournameis.'
>>>t.render(Context({'Name':'hello'}))
u'Yournameis.'
系统静悄悄地表示失败,而不是引发一个异常,因为这通常是人为错误造成的。这种情况下,因为变量名有错误的状况或名称,所有的查询都会失败。现实世界中,对于一个web站点来说,如果仅仅因为一个小的模板语法错误而造成无法访问,这是不可接受的。