2013-12-18 33 views
5

我们有一个自定义Jinja过滤器,我们用它为我们的Javascript和CSS资源创建缓存清除URL。我们现在注意到,在我们的生产环境中,最终的编译模板被缓存。这会导致一个问题,因为我们的模板过滤器有时不会创建一个新的URL(即,当模板没有改变,但是Javascript是)。为某些过滤器禁用Jinja模板缓存

有没有办法强制Jinja每次重新评估某个过滤器而不缓存结果?

编辑1:我们使用常量输入(文件的名称)过滤器。

回答

2

的Jinja2的缓存行为可以使用cache_size设置进行配置:http://jinja.pocoo.org/docs/api/#jinja2.Environment

然而,这仅仅缓存模板本身。只要过滤器的输入是可变的,输出也会变化。

所以...你怎么使用过滤器?你能发布模板的部分和正在缓存的过滤器吗?

+1

是的,我们使用的是恒定的输入值(我们要cachebust的文件名)。 –

+0

我有一个名为'datetimeformat'的自定义过滤器,它格式化传递的日期时间。我添加了一个快捷方式,当''now'| datetimeformat'被使用,它会把当前时间。并发现它不会改变... – warvariuc

+0

@warvariuc:这取决于你如何得到''现在'。如果构建得当,它应该可以正常工作,但是很容易意外地将日期设为静态,从而打破所有更改。 – Wolph

3

有一种方法可以禁用特定过滤器的结果的高速缓存:它是由而不是使用恒定输入,例如,通过将随机源暴露为全局变量。

# Expose to Jinja 
from random import random as RANDOM 

而且在模板

{{ RANDOM() | eval_this_filter_every_time }} 
5

经过大量的谷歌搜索,我终于找到真正的解决了这一点。 Jinja有一个名为contextfilter的特殊帮助程序,您可以使用它来修饰您的函数,使您的过滤器上下文感知(和上下文相关)。 Jinja字节码缓存不会缓存这个计算值,即使当一个常量作为输入传递时也是如此。

在你的过滤器在Python:

from jinja2 import contextfilter 

@contextfilter 
def asset_url(context, url): 
    return some_url_thing(url) 

在模板:

<link rel="stylesheet" href="{{ 'styles.css' | asset_url }}" /> 
+0

很多很多很多,感谢这个! –

+0

这是正确的答案 – b264