Python的Django框架中的Context使用
一旦你创建一个Template对象,你可以用context来传递数据给它。一个context是一系列变量和它们值的集合。
context在Django里表现为Context类,在django.template模块里。她的构造函数带有一个可选的参数:一个字典映射变量和它们的值。调用Template对象的render()方法并传递context来填充模板:
>>>fromdjango.templateimportContext,Template >>>t=Template('Mynameis{{name}}.') >>>c=Context({'name':'Stephane'}) >>>t.render(c) u'MynameisStephane.'
我们必须指出的一点是,t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。你可以通过字符串前的u来区分。在框架中,Django会一直使用Unicode对象而不是普通的字符串。如果你明白这样做给你带来了多大便利的话,尽可能地感激Django在幕后有条不紊地为你所做这这么多工作吧。如果不明白你从中获益了什么,别担心。你只需要知道Django对Unicode的支持,将让你的应用程序轻松地处理各式各样的字符集,而不仅仅是基本的A-Z英文字符。
字典和Contexts
Python的字典数据类型就是关键字和它们值的一个映射。Context和字典很类似,Context还提供更多的功能。
变量名必须由英文字符开始(A-Z或a-z)并可以包含数字字符、下划线和小数点。(小数点在这里有特别的用途,稍后我们会讲到)变量是大小写敏感的。
下面是编写模板并渲染的示例:
>>>fromdjango.templateimportTemplate,Context >>>raw_template="""<p>Dear{{person_name}},</p> ... ...<p>Thanksforplacinganorderfrom{{company}}.It'sscheduledto ...shipon{{ship_date|date:"Fj,Y"}}.</p> ... ...{%ifordered_warranty%} ...<p>Yourwarrantyinformationwillbeincludedinthepackaging.</p> ...{%else%} ...<p>Youdidn'torderawarranty,soyou'reonyourownwhen ...theproductsinevitablystopworking.</p> ...{%endif%} ... ...<p>Sincerely,<br/>{{company}}</p>""" >>>t=Template(raw_template) >>>importdatetime >>>c=Context({'person_name':'JohnSmith', ...'company':'OutdoorEquipment', ...'ship_date':datetime.date(2009,4,2), ...'ordered_warranty':False}) >>>t.render(c) u"<p>DearJohnSmith,</p>\n\n<p>ThanksforplacinganorderfromOutdoor Equipment.It'sscheduledto\nshiponApril2,2009.</p>\n\n\n<p>You didn'torderawarranty,soyou'reonyourownwhen\ntheproducts inevitablystopworking.</p>\n\n\n<p>Sincerely,<br/>OutdoorEquipment </p>"
让我们逐步来分析下这段代码:
首先我们导入(import)类Template和Context,它们都在模块django.template里。
我们把模板原始文本保存到变量raw_template。注意到我们使用了三个引号来标识这些文本,因为这样可以包含多行。
接下来,我们创建了一个模板对象t,把raw_template作为Template类构造函数的参数。
我们从Python的标准库导入datetime模块,以后我们将会使用它。
然后,我们创建一个Context对象,c。Context构造的参数是Python字典数据类型。在这里,我们指定参数person_name的值是'JohnSmith',参数company的值为‘OutdoorEquipment',等等。
最后,我们在模板对象上调用render()方法,传递context参数给它。这是返回渲染后的模板的方法,它会替换模板变量为真实的值和执行块标签。
注意,warrantyparagraph显示是因为ordered_warranty的值为True.注意时间的显示,April2,2009,它是按'Fj,Y'格式显示的。
如果你是Python初学者,你可能在想为什么输出里有回车换行的字符('\n')而不是显示回车换行?因为这是Python交互解释器的缘故:调用t.render(c)返回字符串,解释器缺省显示这些字符串的真实内容呈现,而不是打印这个变量的值。要显示换行而不是'\n',使用print语句:printt.render(c)。
这就是使用Django模板系统的基本规则:写模板,创建Template对象,创建Context,调用render()方法。
同一模板,多个上下文
一旦有了模板对象,你就可以通过它渲染多个context,例如:
>>>fromdjango.templateimportTemplate,Context >>>t=Template('Hello,{{name}}') >>>printt.render(Context({'name':'John'})) Hello,John >>>printt.render(Context({'name':'Julie'})) Hello,Julie >>>printt.render(Context({'name':'Pat'})) Hello,Pat
无论何时我们都可以像这样使用同一模板源渲染多个context,只进行一次模板创建然后多次调用render()方法渲染会更为高效:
#Bad fornamein('John','Julie','Pat'): t=Template('Hello,{{name}}') printt.render(Context({'name':name})) #Good t=Template('Hello,{{name}}') fornamein('John','Julie','Pat'): printt.render(Context({'name':name}))
Django模板解析非常快捷。大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。这和基于XML的模板引擎形成鲜明对比,那些引擎承担了XML解析器的开销,且往往比Django模板渲染引擎要慢上几个数量级。