如何强制Jinja2模板重新编译?

时间:2020-12-11 20:50:32

I'm trying to switch Jinja2 template in the django app without restarting the application.

我正在尝试在django应用程序中切换Jinja2模板而不重新启动应用程序。

Has anyone done this? Basically I need to force jinja2 to reload the templates once the skin selection change is applied.

有没有人这样做过?基本上我需要在应用皮肤选择更改后强制jinja2重新加载模板。

I've tried to re-create cache object on the template environment object with no effect.

我试图在模板环境对象上重新创建缓存对象而没有任何效果。

myskin_utils.py:

from jinja2.environment import create_cache
ENV_OBJECT.cache = create_cache(50)

I've also tried to reload the module that contains my ENV_OBJECT with

我也尝试重新加载包含我的ENV_OBJECT的模块

reload(myskin) #also no effect on the output

Another thing I'd like to change on the fly is language, but I guess it's a separate question.

我想要动态改变的另一件事是语言,但我想这是一个单独的问题。

Thanks for any advice.

谢谢你的建议。

edit: I don't have cache set up with jinja2, but I do see a speed up from using Jinja after switching from Django templates, I suspect that template bytecode lives in the compiled code of my view functions but I did not look into details of jinja.

编辑:我没有使用jinja2设置缓存,但我确实看到从Django模板切换后使用Jinja加速,我怀疑模板字节码存在于我的视图函数的编译代码中,但我没有查看详细信息神社

I have ENV (an instance of CoffinEnvironment which subclasses Jinja's Environment) imported in the global namespace of a view module and calls ENV.get_template() inside view functions (Django+Coffin+Jinja2).

我在视图模块的全局命名空间中导入了ENV(一个CoffinEnvironment实例,它是Jinja环境的子类),并在视图函数(Django + Coffin + Jinja2)中调用ENV.get_template()。

Found that if I call python's reload() builtin on my environment module within the view function the template does switch, but I would not like to stick that code into every function.

发现如果我在视图函数中调用python的reload()内置在我的环境模块中,模板会切换,但我不想将该代码粘贴到每个函数中。

2 个解决方案

#1


4  

Per default Jinja2 doesn't use any caching at all, but it's recommended to configure a caching backend to speed things up a little bit. So that jinja2 doesn't have to parse and compile every template on every requests. Jinja2 supports currently 2 different cache types out of the box:

默认情况下,Jinja2根本不使用任何缓存,但建议配置缓存后端以加快速度。这样jinja2就不必在每个请求上解析和编译每个模板。 Jinja2目前支持2种不同的缓存类型:

One of them is FileSystemBytecodeCache which is (like the name suggests) file based. So all compiled templates are stored on the file system and retrieved from there. If you look closely at the implementation, you will also find a cache.clear() method there which simply deletes all files in this temporary folder. Causing all templates to be parsed/compiled again.

其中一个是FileSystemBytecodeCache,它(就像名字所示)基于文件。因此,所有编译的模板都存储在文件系统中并从那里检索。如果仔细查看实现,您还会发现cache.clear()方法,它只删除此临时文件夹中的所有文件。导致所有模板再次被解析/编译。

The other cache type is a called MemcachedBytecodeCache which is just a thin wrapper for Memcache. This method is recommended, because Memcache stores everything in memory, so it's a little bit faster than hitting the disk, and you can use the same cache from different hosts (which is useful if you are running some kind of cluster).

另一种缓存类型是一个名为MemcachedBytecodeCache的文件,它只是Memcache的一个瘦包装器。建议使用此方法,因为Memcache将所有内容存储在内存中,因此它比命中磁盘快一点,并且您可以使用来自不同主机的相同缓存(如果您运行某种类型的集群,这很有用)。

The underlying Memcache client (either werkzeug.contrib.cache, python-memcached or cmemcache) does also provide a clear() method which will delete everything inside the cache. But because you probably use the cache for other things too (e.g. storing the result of expensive database queries there), the clear() method isn't exposed in jinja, because it will affect everything (and not just the templates).

底层的Memcache客户端(werkzeug.contrib.cache,python-memcached或cmemcache)也提供了一个clear()方法,它将删除缓存中的所有内容。但是因为你可能也使用缓存来处理其他事情(比如存储昂贵的数据库查询的结果),所以clear()方法不会在jinja中公开,因为它会影响一切(而不仅仅是模板)。

So, to summarize your options are:

所以,总结一下你的选择是:

  • Use Jinja2 without a Cache
  • 使用没有缓存的Jinja2

  • Use Jinja2 with a FileSystemBytecodeCache and call cache.clear()
  • 将Jinja2与FileSystemBytecodeCache一起使用并调用cache.clear()

  • Use Jinja2 with a MemcachedBytecodeCache and call memcache_client.clear() (which will also clear everything else in the cache).
  • 将Jinja2与MemcachedBytecodeCache一起使用并调用memcache_client.clear()(它也将清除缓存中的所有其他内容)。

  • Run a separate memcached process on another port which is only used with Jinja2. Then call memcache_client.clear() and all templates will be cleared.
  • 在另一个仅与Jinja2一起使用的端口上运行单独的memcached进程。然后调用memcache_client.clear()并清除所有模板。

#2


0  

This is wrong. Jinja uses a LRUCache in memory cache by default, of cache_size (Environment parameter). You can use a disk cache to make subsequent restarts of the app preformant too (no recompilation needed).

这是错的。 Jinja默认使用内存缓存中的LRUCache,即cache_size(Environment参数)。您也可以使用磁盘缓存来重新启动app preformant(无需重新编译)。

#1


4  

Per default Jinja2 doesn't use any caching at all, but it's recommended to configure a caching backend to speed things up a little bit. So that jinja2 doesn't have to parse and compile every template on every requests. Jinja2 supports currently 2 different cache types out of the box:

默认情况下,Jinja2根本不使用任何缓存,但建议配置缓存后端以加快速度。这样jinja2就不必在每个请求上解析和编译每个模板。 Jinja2目前支持2种不同的缓存类型:

One of them is FileSystemBytecodeCache which is (like the name suggests) file based. So all compiled templates are stored on the file system and retrieved from there. If you look closely at the implementation, you will also find a cache.clear() method there which simply deletes all files in this temporary folder. Causing all templates to be parsed/compiled again.

其中一个是FileSystemBytecodeCache,它(就像名字所示)基于文件。因此,所有编译的模板都存储在文件系统中并从那里检索。如果仔细查看实现,您还会发现cache.clear()方法,它只删除此临时文件夹中的所有文件。导致所有模板再次被解析/编译。

The other cache type is a called MemcachedBytecodeCache which is just a thin wrapper for Memcache. This method is recommended, because Memcache stores everything in memory, so it's a little bit faster than hitting the disk, and you can use the same cache from different hosts (which is useful if you are running some kind of cluster).

另一种缓存类型是一个名为MemcachedBytecodeCache的文件,它只是Memcache的一个瘦包装器。建议使用此方法,因为Memcache将所有内容存储在内存中,因此它比命中磁盘快一点,并且您可以使用来自不同主机的相同缓存(如果您运行某种类型的集群,这很有用)。

The underlying Memcache client (either werkzeug.contrib.cache, python-memcached or cmemcache) does also provide a clear() method which will delete everything inside the cache. But because you probably use the cache for other things too (e.g. storing the result of expensive database queries there), the clear() method isn't exposed in jinja, because it will affect everything (and not just the templates).

底层的Memcache客户端(werkzeug.contrib.cache,python-memcached或cmemcache)也提供了一个clear()方法,它将删除缓存中的所有内容。但是因为你可能也使用缓存来处理其他事情(比如存储昂贵的数据库查询的结果),所以clear()方法不会在jinja中公开,因为它会影响一切(而不仅仅是模板)。

So, to summarize your options are:

所以,总结一下你的选择是:

  • Use Jinja2 without a Cache
  • 使用没有缓存的Jinja2

  • Use Jinja2 with a FileSystemBytecodeCache and call cache.clear()
  • 将Jinja2与FileSystemBytecodeCache一起使用并调用cache.clear()

  • Use Jinja2 with a MemcachedBytecodeCache and call memcache_client.clear() (which will also clear everything else in the cache).
  • 将Jinja2与MemcachedBytecodeCache一起使用并调用memcache_client.clear()(它也将清除缓存中的所有其他内容)。

  • Run a separate memcached process on another port which is only used with Jinja2. Then call memcache_client.clear() and all templates will be cleared.
  • 在另一个仅与Jinja2一起使用的端口上运行单独的memcached进程。然后调用memcache_client.clear()并清除所有模板。

#2


0  

This is wrong. Jinja uses a LRUCache in memory cache by default, of cache_size (Environment parameter). You can use a disk cache to make subsequent restarts of the app preformant too (no recompilation needed).

这是错的。 Jinja默认使用内存缓存中的LRUCache,即cache_size(Environment参数)。您也可以使用磁盘缓存来重新启动app preformant(无需重新编译)。