在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站点来说,如果仅仅因为一个小的模板语法错误而造成无法访问,这是不可接受的。