自定义模板后端 — Django 文档

来自菜鸟教程
Django/docs/3.1.x/howto/custom-template-backend
跳转至:导航、​搜索

自定义模板后端

自定义后端

以下是如何实现自定义模板后端以使用另一个模板系统。 模板后端是一个继承 django.template.backends.base.BaseEngine 的类。 它必须实现 get_template() 和可选的 from_string()。 下面是一个虚构的 foobar 模板库的示例:

from django.template import TemplateDoesNotExist, TemplateSyntaxError
from django.template.backends.base import BaseEngine
from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy

import foobar


class FooBar(BaseEngine):

    # Name of the subdirectory containing the templates for this engine
    # inside an installed application.
    app_dirname = 'foobar'

    def __init__(self, params):
        params = params.copy()
        options = params.pop('OPTIONS').copy()
        super().__init__(params)

        self.engine = foobar.Engine(**options)

    def from_string(self, template_code):
        try:
            return Template(self.engine.from_string(template_code))
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)

    def get_template(self, template_name):
        try:
            return Template(self.engine.get_template(template_name))
        except foobar.TemplateNotFound as exc:
            raise TemplateDoesNotExist(exc.args, backend=self)
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)


class Template:

    def __init__(self, template):
        self.template = template

    def render(self, context=None, request=None):
        if context is None:
            context = {}
        if request is not None:
            context['request'] = request
            context['csrf_input'] = csrf_input_lazy(request)
            context['csrf_token'] = csrf_token_lazy(request)
        return self.template.render(context)

有关详细信息,请参阅 DEP 182


自定义引擎的调试集成

Django 调试页面具有钩子,可在出现模板错误时提供详细信息。 自定义模板引擎可以使用这些钩子来增强向用户显示的回溯信息。 以下挂钩可用:

模板事后分析

当提出 TemplateDoesNotExist 时,会出现事后分析。 它列出了在尝试查找给定模板时使用的模板引擎和加载器。 例如,如果配置了两个 Django 引擎,事后分析将显示为:

../_images/postmortem.png 自定义引擎可以通过在引发 TemplateDoesNotExist 时传递 backendtried 参数来填充事后分析。 使用事后分析 的后端应在模板对象上指定原点


上下文线路信息

如果在模板解析或渲染过程中发生错误,Django 可以显示发生错误的行。 例如:

../_images/template-lines.png 自定义引擎可以通过在解析和呈现期间引发的异常设置 template_debug 属性来填充此信息。 该属性是一个 dict,具有以下值:

  • 'name':发生异常的模板名称。
  • 'message':异常信息。
  • 'source_lines':发生异常的行之前、之后和包括行。 这是用于上下文的,因此它不应包含超过 20 行左右。
  • 'line':发生异常的行号。
  • 'before':在引发错误的标记之前的错误行上的内容。
  • 'during':引发错误的令牌。
  • 'after':在引发错误的标记之后的错误行上的内容。
  • 'total'source_lines中的行数。
  • 'top'source_lines开始的行号。
  • 'bottom'source_lines结束的行号。

鉴于上述模板错误,template_debug 将如下所示:

{
    'name': '/path/to/template.html',
    'message': "Invalid block tag: 'syntax'",
    'source_lines': [
        (1, 'some\n'),
        (2, 'lines\n'),
        (3, 'before\n'),
        (4, 'Hello {% syntax error %} {{ world }}\n'),
        (5, 'some\n'),
        (6, 'lines\n'),
        (7, 'after\n'),
        (8, ''),
    ],
    'line': 4,
    'before': 'Hello ',
    'during': '{% syntax error %}',
    'after': ' {{ world }}\n',
    'total': 9,
    'bottom': 9,
    'top': 1,
}

Origin API 和第三方集成

Django 模板有一个 Origin 对象,可通过 template.origin 属性使用。 这使调试信息能够显示在 模板 postmortem 中,以及在 3rd-party 库中,如 Django 调试工具栏

自定义引擎可以通过创建指定以下属性的对象来提供自己的 template.origin 信息:

  • 'name':模板的完整路径。
  • 'template_name':传递给模板加载方法的模板的相对路径。
  • 'loader_name':标识用于加载模板的函数或类的可选字符串,例如 django.template.loaders.filesystem.Loader