データベースに保存される独自の Jinja2 テンプレートを作成するユーザー (非常にサンドボックス化された環境で、うんざりする人のために) を持つ Django SaaS アプリがあります。template_type
特定のテンプレートが「インクルード」または「完全なテンプレート」であるかどうかを示すフィールドがあります(完全なテンプレートにはもちろん「インクルード」を含めることができます)。問題は、ユーザーが{% include "foo" %}
と呼ばれるテンプレートや"bar"
テンプレートに入力する可能性があり、その結果、パフォーマンスが良くないタイプの状況が発生する可能性があることです。{% include "bar" %}
"foo"
RuntimeError: maximum recursion depth exceeded
検証正規表現が含まれていないこの状況を処理する良い方法はありますか (例: r'\{%\s+include'
) ユーザー テンプレートの作成時にインクルードをチェックします (「再帰インポートがデータベースに取得されないことを確認してください。そうしないと、サーバーが爆発することを確認してください」はありません)。 t は私とかなりジャイブ)。
私の失敗した試み
ユーザーの「インクルード」のみを含むカスタムローダーを使用することから始めました::
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(...
。