ySJ
|
2.0/chapter09/#386 |
2010-04-16 13:05:36
|
如果出现错误,应该返回一个原始输入或者空字符串,这会更有意义。
|
|
ySJ
|
2.0/chapter09/#366 |
2010-04-16 10:59:06
|
注意
|
|
ySJ
|
2.0/chapter09/#363 |
2010-04-16 10:58:56
|
所以,请在你的模块的顶部插入如下语句:
|
|
ySJ
|
2.0/chapter09/#362 |
2010-04-16 10:58:13
|
作为合法的标签库,模块需要包含一个名为<literal>register</literal>的模块级变量。这个变量是<literal>template.Library</literal>的实例,是所有注册标签和过滤器的数据结构。
|
|
ySJ
|
2.0/chapter09/#299 |
2010-04-15 19:54:06
|
对 <literal>INSTALLED_APPS</literal> 中的每个应用,这个加载器会查找<literal>templates</literal> 子目录。
|
|
ySJ
|
2.0/chapter09/#323 |
2010-04-16 10:06:56
|
既然你已经对模板系统的内幕多了一些了解,让我们来看看如何使用自定义的代码来扩展这个系统吧。
|
|
ySJ
|
2.0/chapter09/#335 |
2010-04-16 10:18:16
|
第一,决定模板库应该放在哪个Django应用下。
|
|
ySJ
|
2.0/chapter09/#337 |
2010-04-16 10:18:52
|
我们更推荐使用后者,因为你的filter可能在后来的工程中有用。
|
|
ySJ
|
2.0/chapter09/#339 |
2010-04-16 10:19:30
|
无论你采用何种方式,请确保把你的应用添加到 <literal>INSTALLED_APPS</literal> 中。
|
|
ySJ
|
2.0/chapter09/#340 |
2010-04-16 10:19:37
|
我们稍后会解释这一点。
|
|
ySJ
|
2.0/chapter09/#344 |
2010-04-16 10:20:08
|
例如:
|
|
ySJ
|
2.0/chapter09/#356 |
2010-04-16 10:45:23
|
如果你打算写一个不和任何特定模型/视图关联的模板库,那么一个仅包含 <literal>templatetags</literal> 包的Django应用程序包就是很普遍的了。
|
|
ySJ
|
2.0/chapter09/#358 |
2010-04-16 10:47:38
|
需要了解的是:<literal>{%load%}</literal>语句是通过指定的Python模块名而不是应用名来加载标签/过滤器的。
|
|
ySJ
|
2.0/chapter09/#362 |
2010-04-16 10:57:36
|
作为合法的标签库,模块需要包含一个名为<literal>register</literal>的模块机变量。它是<literal>template.Library</literal>的实例,是所有注册标签和过滤器的数据结构。
|
|
ySJ
|
2.0/chapter09/#391 |
2010-04-16 13:06:28
|
下面是一个可以用来去掉变量值空格的过滤器例子:
|
|
ySJ
|
2.0/chapter09/#398 |
2010-04-16 13:09:33
|
当你定义完过滤器后,你需要用 <literal>Library</literal> 实例来注册它,这样就能通过Django的模板语言来使用了:
|
|
ySJ
|
2.0/chapter09/#407 |
2010-04-16 13:10:39
|
如果你使用的是Python 2.4或者更新的版本,你可以把 <literal>register.filter()</literal>作一个装饰器:
|
|
ySJ
|
2.0/chapter09/#439 |
2010-04-16 13:21:32
|
IfEqual节点:
|
|
ySJ
|
2.0/chapter09/#440 |
2010-04-16 13:22:08
|
<literal>name.birthday</literal>和<literal>today</literal> |
|
ySJ
|
2.0/chapter09/#442 |
2010-04-16 13:23:58
|
当你调用一个已编译模板的 <literal>render()</literal> 方法时,模板就会用给定的context来调用每个在它的节点列表上的所有节点的 <literal>render()</literal> 方法。
|
|
ySJ
|
2.0/chapter09/#443 |
2010-04-16 13:27:54
|
这些渲染的结果合并起来,形成了模板的输出。
|
|
ySJ
|
2.0/chapter09/#444 |
2010-04-16 13:50:52
|
因此,要自定义模板标签,你需要指明原始模板标签如何转换成<literal>节点</literal>(编译函数)和节点的<literal>render()</literal>方法完成的功能 。
|
|
ySJ
|
2.0/chapter09/#453 |
2010-04-16 13:58:00
|
例如,写一个显示当前日期的模板标签:{% current_time %}。该标签会根据参数指定的 strftime 格式(参见:<literal>http://www.djangoproject.com/r/python/strftime/</literal>)显示当前时间。首先确定标签的语法是个好主意。
|
|
ySJ
|
2.0/chapter09/#454 |
2010-04-16 14:09:33
|
在这个例子里,标签应该这样使用:
|
|
ySJ
|
2.0/chapter09/#465 |
2010-04-16 14:11:58
|
这里需要说明的地方很多:
|
|
ySJ
|
2.0/chapter09/#467 |
2010-04-16 14:14:53
|
每个标签编译函数有两个参数,<literal>parser</literal>和<literal>token</literal>。<literal>parser</literal>是模板解析器对象。
|
|
ySJ
|
2.0/chapter09/#469 |
2010-04-16 14:16:29
|
<literal>token</literal>是正在被解析的语句。
|
|
ySJ
|
2.0/chapter09/#474 |
2010-04-16 14:21:16
|
<literal>token.split_contents()</literal> 方法按空格拆分参数同时保证引号中的字符串不拆分。
|
|
ySJ
|
2.0/chapter09/#437 |
2010-04-16 13:20:56
|
<literal>".\n\n"</literal> |
|
ySJ
|
2.0/chapter09/#436 |
2010-04-16 13:20:26
|
文本节点:
|
|
ySJ
|
2.0/chapter09/#410 |
2010-04-16 13:13:37
|
如果你想第二个例子那样不使用 <literal>name</literal> 参数,那么Django会把函数名当作过滤器的名字。
|
|
ySJ
|
2.0/chapter09/#407 |
2010-04-16 13:11:21
|
如果你使用的是Python 2.4或者更新的版本,你可以使用装饰器<literal>register.filter()</literal>:
|
|
ySJ
|
2.0/chapter09/#417 |
2010-04-16 13:15:13
|
标签要比过滤器复杂些,因为标签几乎能做任何事情。
|
|
ySJ
|
2.0/chapter09/#421 |
2010-04-16 13:16:46
|
为了自定义一个模板标签,你需要告诉Django当遇到你的标签时怎样进行这个过程。
|
|
ySJ
|
2.0/chapter09/#424 |
2010-04-16 13:17:43
|
于是,一个已编译的模板就是 <literal>节点</literal> 对象的一个列表。
|
|
ySJ
|
2.0/chapter09/#431 |
2010-04-16 13:18:32
|
<literal>"Hello, "</literal> |
|
ySJ
|
2.0/chapter09/#428 |
2010-04-16 13:19:25
|
被编译的模板表现为节点列表的形式:
|
|
ySJ
|
2.0/chapter09/#433 |
2010-04-16 13:19:45
|
变量节点:
|
|
ySJ
|
2.0/chapter09/#434 |
2010-04-16 13:20:07
|
<literal>person.name</literal> |
|
ySJ
|
2.0/chapter09/#412 |
2010-04-16 13:14:46
|
下面是一个完整的模板库的例子,它包含一个 <literal>cut</literal> 过滤器:
|
|
yukonli
|
2.0/chapter08/#371 |
2009-12-15 17:23:43
|
然而,当我们做到这一步时,我们仍然可以改进method_splitter。从代码我们可以看到,它假设Get和POST视图除了request之外不需要任何其他的参数。那么,假如我们想要使用method_splitter与那种会从URL里捕捉字符,或者会接收一些可选参数的视图一起工作时该怎么办呢?
|
|
yukonli
|
2.0/chapter08/#371 |
2009-12-15 18:00:44
|
然而,当我们做到这一步时,我们仍然可以改进<literal> method_splitter</literal> 。从代码我们可以看到,它假设<literal> Get</literal> 和<literal> POST</literal> 视图除了<literal> request</literal> 之外不需要任何其他的参数。那么,假如我们想要使用<literal> method_splitter</literal> 与那种会从URL里捕捉字符,或者会接收一些可选参数的视图一起工作时该怎么办呢?
|
|
yukonli
|
2.0/chapter08/#291 |
2009-12-15 16:43:01
|
比方说,你可以考虑通过下面这个URLpattern所描述的方式来向Django的管理站点添加一个目标页面
|
|
yulefox
|
2.0/chapter01/#180 |
2010-02-09 09:13:03
|
如果你有Python开发经验,在学习过程中应该不会有任何问题。
|
|
yulefox
|
2.0/chapter01/#182 |
2010-02-09 09:14:17
|
对你来说,学习Django就是学习她的命名规则和API。
|
|
yulefox
|
2.0/chapter01/#24 |
2010-02-09 09:10:30
|
最重要的是,理解实现的<emphasis></emphasis>会使你成为一个优秀的web开发者。)
|
|
yulefox
|
2.0/chapter20/#56 |
2010-02-08 18:04:28
|
此时,查询的字符串会构造如下:
|
|
yulefox
|
2.0/chapter20/#55 |
2010-02-08 18:04:10
|
想象一下,如果攻击者在查询框中输入 <literal>"' OR 'a'='a"</literal> 。
|
移到下一句
|
yulefox
|
2.0/chapter01/#181 |
2010-02-09 09:13:57
|
基本上,Django的代码并 没有使用一些黑色魔法(例如代码中的欺骗行为,某个实现解释或者理解起来十分困难)。
|
|
yulefox
|
2.0/chapter01/#24 |
2010-02-09 09:11:03
|
最重要的是,理解实现的来龙去脉会使你成为一个优秀的web开发者。)
|
|