一、概述
想要定制或者扩展模版引擎,模版系统工作原理,自动转移特征
名词解析:模板 渲染 就是是通过从context获取值来替换模板中变量并执行所有的模板标签。
二、Context处理器
如果在模版中经常使用相同的模版变量,这是会产生大量的代码冗余,可以通过RequestContext来解决这个问题。
例如:
from django.template import loader, Context def view_1(request): # ... t = loader.get_template('template1.html') c = Context({ 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'], 'message': 'I am view 1.' }) return t.render(c) def view_2(request): # ... t = loader.get_template('template2.html') c = Context({ 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'], 'message': 'I am the second view.' }) return t.render(c)
有相同的'app','user','ip_address',我们可以通过RequestContext来解决,第一个参数:视图函数传进来的request对象,第二个参数:额外的需要渲染的模版变量,第三个参数:可选参数processors是一个context处理器列表或元组。context处理器是一个函数,返回一个模版Context变量字典。
from django.template import loader, RequestContext def custom_proc(request): "A context processor that provides 'app', 'user' and 'ip_address'." return { 'app': 'My app', 'user': request.user, 'ip_address': request.META['REMOTE_ADDR'] } def view_1(request): # ... t = loader.get_template('template1.html') c = RequestContext(request, {'message': 'I am view 1.'}, processors=[custom_proc]) return t.render(c) def view_2(request): # ... t = loader.get_template('template2.html') c = RequestContext(request, {'message': 'I am the second view.'}, processors=[custom_proc]) return t.render(c)
三、Django提供了 全局 context处理器的支持
TEMPLATE_CONTEXT_PROCESSORS 指定了哪些context processors总是默认被使用。这样就省去了每次使用 RequestContext 都指定 processors 的麻烦。在setting文件中可以找到
TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', )
每一项都是可调用函数,跟上面的custom_proc 有相同的接口。向其中添加的context处理器函数路径,都应该包含在系统path的搜索路径。
每个处理器将会按照顺序应用。 也就是说如果你在第一个处理器里面向context添加了一个变量,而第二个处理器添加了同样名字的变量,那么第二个将会覆盖第一个。
写Context处理器的一些建议
-
使每个context处理器完成尽可能小的功能。 使用多个处理器是很容易的,所以你可以根据逻辑块来分解功能以便将来复用。
-
要注意 TEMPLATE_CONTEXT_PROCESSORS 里的context processor 将会在基于这个settings.py的每个 模板中有效,所以变量的命名不要和模板的变量冲突。 变量名是大小写敏感的,所以processor的变量全用大写是个不错的主意。
-
不论它们存放在哪个物理路径下,只要在你的Python搜索路径中,你就可以在TEMPLATE_CONTEXT_PROCESSORS 设置里指向它们。 建议你把它们放在应用或者工程目录下名为context_processors.py 的文件里。
四、html自动转意,django里默认情况下,每一个模板自动转意每一个变量标签的输出。主要是解决用户提交的数据不应该完全被信任,有可能是有恶意用途的字符串
比如:用户输入了<script>alert('hello')</script>,如果将这个字符串直接显示,将会弹出一个警告框。而不是输入用户的名字。
如果你不想数据被自动转意,在每一站点级别、每一模板级别或者每一变量级别你都有几种方法来关闭它
对于单独的变量
用safe过滤器为单独的变量关闭自动转意:
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
对于模板块
为了控制模板的自动转意,用标签autoescape来包装整个模板(或者模板中常用的部分),autoescape 标签有两个参数on和off 。就像这样:
Auto-escaping is on by default. Hello {{ name }} {% autoescape off %} This will not be auto-escaped: {{ data }}. Nor this: {{ other_data }} {% autoescape on %} Auto-escaping applies again: {{ name }} {% endautoescape %} {% endautoescape %}
五、加载模版的方法
django.template.loaders.filesystem.load_template_source : 这个加载器根据 TEMPLATE_DIRS 的设置从文件系统加载模板。它默认是可用的。
django.template.loaders.app_directories.load_template_source : 这个加 载器从文件系统上的Django应用中加载模板。 对 INSTALLED_APPS 中的每个应用,这个加载器会查找templates 子目录。 如果这个目录存在,Django就在那里寻找模板。这个加载器默认启用。