- 编写自定义模板加载器
编写自定义模板加载器
Djangos 内置的模板加载器(在先前的模板加载内幕章节有叙述)通常会满足你的所有的模板加载需求,但是如果你有特殊的加载需求的话,编写自己的模板加载器也会相当简单。 比如:你可以从数据库中,或者利用Python的绑定直接从Subversion库中,更或者从一个ZIP文档中加载模板。
模板加载器,也就是 TEMPLATE_LOADERS
中的每一项,都要能被下面这个接口调用:
load_template_source(template_name, template_dirs=None)
参数 template_name
是所加载模板的名称 (和传递给 loader.get_template()
或者 loader.select_template()
一样), 而 template_dirs
是一个可选的代替TEMPLATE_DIRS
的搜索目录列表。
如果加载器能够成功加载一个模板, 它应当返回一个元组: (template_source, template_path)
。在这里的 template_source
就是将被模板引擎编译的的模板字符串,而 template_path
是被加载的模板的路径。 由于那个路径可能会出于调试目的显示给用户,因此它应当很快的指明模板从哪里加载。
如果加载器加载模板失败,那么就会触发 django.template.TemplateDoesNotExist
异常。
每个加载函数都应该有一个名为 is_usable
的函数属性。 这个属性是一个布尔值,用于告知模板引擎这个加载器是否在当前安装的Python中可用。 例如,如果 pkg_resources
模块没有安装的话,eggs加载器(它能够从python eggs中加载模板)就应该把 is_usable
设为 False
,因为必须通过 pkg_resources
才能从eggs中读取数据。
一个例子可以清晰地阐明一切。 这儿是一个模板加载函数,它可以从ZIP文件中加载模板。 它使用了自定义的设置 TEMPLATE_ZIP_FILES
来取代了 TEMPLATE_DIRS
用作查找路径,并且它假设在此路径上的每一个文件都是包含模板的ZIP文件:
from django.conf import settings
from django.template import TemplateDoesNotExist
import zipfile
def load_template_source(template_name, template_dirs=None):
"Template loader that loads templates from a ZIP file."
template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", [])
# Try each ZIP file in TEMPLATE_ZIP_FILES.
for fname in template_zipfiles:
try:
z = zipfile.ZipFile(fname)
source = z.read(template_name)
except (IOError, KeyError):
continue
z.close()
# We found a template, so return the source.
template_path = "%s:%s" % (fname, template_name)
return (source, template_path)
# If we reach here, the template couldn't be loaded
raise TemplateDoesNotExist(template_name)
# This loader is always usable (since zipfile is included with Python)
load_template_source.is_usable = True
我们要想使用它,还差最后一步,就是把它加入到 TEMPLATE_LOADERS
。 如果我们将这个代码放入一个叫mysite.zip_loader的包中,那么我们要把mysite.zip_loader.load_template_source加到TEMPLATE_LOADERS中。