3

我有一个 Django SaaS 应用程序,用户创建了自己的 Jinja2 模板(在一个非常沙盒环境中,对于那些只是畏缩的人),这些模板保存到数据库中。我有一个template_type字段,指出给定模板是“包含”还是“完整模板”(完整模板当然可以包含“包含”)。问题是用户可以将{% include "foo" %}一个名为"bar"的模板{% include "bar" %}放入"foo"模板中,从而导致一种RuntimeError: maximum recursion depth exceeded不利于性能的情况。

有没有一种很好的方法来处理这种情况,它不包括验证正则表达式(例如,r'\{%\s+include')在用户模板创建期间检查包含(“确保递归导入永远不会进入数据库,否则你的服务器将崩溃”不'不太喜欢我)。

我失败的尝试

我首先使用了一个自定义加载器,它只包含用户的“包含”::

def get_source(self, environment, template):
    """
    Returns the source of the template or raises ``TemplateNotFound``.
    This loader is for use with an environment which intends to load each
    template from a string, since only includes are loaded from here.
    """
    try:
        template = self.snippets[template]
    except KeyError:
        raise jinja2.TemplateNotFound(
            template, message=u'Snippet "{s}" was not found'.format(s=template)
        )
    else:
        source = template['source']
        return (source, None, lambda: True)

这样做的问题是我基本上阻止了自己利用 Jinja2 的Bytecode Cache,这显然要求所有模板都可用于load(...调用,而调用get_source(....

4

1 回答 1

3

要解析模板并检查包含,我使用以下代码:

    ast = env.parse(template_text)
    for each in meta.find_referenced_templates(ast) :        # find the (% includes %}
于 2012-11-13T12:06:11.513 回答