10

開発には、Bottle.py と Google App Engine の dev_appserver で Jinja2 テンプレートを使用しています。サーバーを再起動し続ける必要がないように、リクエストごとに (または理想的にはテンプレートが変更された場合にのみ) テンプレートを自動的に再読み込みする必要があります。

bottle's docs によると、 を呼び出すことでテンプレートのキャッシュを無効にできるはずですbottle.debug(True)

ただし、Jinja はまだテンプレートをキャッシュしているようです。これは、ボトル jinja2 アダプターの記述方法によるものだと思います (デフォルトの Jinja2 ローダーを使用するだけで、多くの構成オプションを公開していません)。

Jinja2 Docsに従って、毎回テンプレートのリロードをトリガーすることを期待するこのカスタム ローダーを作成しましたが、どちらも機能していないようです。

import settings
from bottle import jinja2_template
from bottle import Jinja2Template, template as base_template
class AutoreloadJinja2Template(Jinja2Template):
    def loader(self, name):
        def uptodate():
            # Always reload the template if we're in DEVMODE (a boolean flag)
            return not settings.DEVMODE
        fname = self.search(name, self.lookup)
        if fname:
            with open(fname, "rb") as f:
                source = f.read().decode(self.encoding)
            return (source, fname, uptodate)


template = functools.partial(base_template,
    template_adapter=AutoreloadJinja2Template,
    template_lookup = settings.TEMPLATE_PATHS,
    template_settings={
        'auto_reload': settings.DEVMODE
    }
)

dev_appserver を再起動するまで、テンプレートは引き続きキャッシュされます。これはかなり一般的な問題です。誰かがうまくいく解決策を持っていますか?

アップデート:

私は最終的に次のようなことをしました:

class CustomJinja2Template(Jinja2Template):
   if settings.DEVMODE:
       def prepare(self, *args, **kwargs):
           kwargs.update({'cache_size':0})
           return Jinja2Template.prepare(self, *args, **kwargs)

template = functools.partial(original_template, template_adapter=CustomJinja2Template)

これにより、テンプレートが常にリロードされますが、Python モジュールが変更された場合のみです。つまり、テンプレート ファイルを編集しただけでは、それをインポートする python ファイルの 1 つを編集するまで、変更は有効になりません。テンプレートがまだどこかにキャッシュされているようです。

4

4 に答える 4

6

ボトルはテンプレートを内部的にキャッシュします (Jinja2 キャッシュとは独立しています)。でキャッシュを無効にするbottle.debug(True)bottle.run(..., debug=True)、 でキャッシュをクリアできbottle.TEMPLATES.clear()ます。

于 2012-02-02T13:03:41.447 に答える
6

ボトルのテンプレート ソリューションを完全に捨てて、純粋な jinja2 を使用することで、この問題を解決しました。FileSystemLoaderファイルの変更を監視できるのは Jijnja だけのようです。

新しいtemplate関数を次のように定義しました (これは、views/以前のボトルのように 内のファイルを検索します)。

from jinja2 import Environment, FileSystemLoader

if local_settings.DEBUG:
    jinja2_env = Environment(loader=FileSystemLoader('views/'), cache_size=0)
else:
    jinja2_env = Environment(loader=FileSystemLoader('views/'))

def template(name, ctx):
    t = jinja2_env.get_template(name)
    return t.render(**ctx)

次に、次のように使用します。

@route('/hello')
def hello():
    return template('index.tpl', {'text': "hello"})

ボトルの API との違いは.tpl、ファイル名に含める必要があることと、コンテキスト変数を辞書として渡す必要があることです。

于 2012-02-22T13:17:24.177 に答える
3

jinja2のEnvironmentオブジェクトには、キャッシュ サイズの構成値があり、ドキュメントによると、

キャッシュ サイズが 0 に設定されている場合、テンプレートは常に再コンパイルされます。

このようなことを試しましたか?

from jinja2 import Environment
env = Environment(cache_size=0)
于 2011-12-22T20:33:46.793 に答える
1

ボトルビューデコレータを使用すると、次のことができます@view('your_view', cache_size=0)

ボトルにはreloader=Trueサーバーアダプターのパラメーターがありますが、SimpleTemplateでのみ機能すると思います。この動作を他のテンプレートエンジンに拡張してみます。

すべてのビューでそれを実行したい場合は、次のようなことを実行できます。

import functools
view = functools.partials(view, cache_size=0)

このように、このコードにifステートメントを追加するデバッグモードの場合にのみ実行できますif bottle.DEBUG

于 2011-12-25T13:31:00.067 に答える