10

我最初使用 App Engine 站点上显示的示例在 App Engine 上实现了 Jinja2:https ://developers.google.com/appengine/docs/python/gettingstartedpython27/templates其中 jinja2 是直接导入的:

import jinja2
import os

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))

class MainPage(webapp2.RequestHandler):
    def get(self):
        greetings = 'somestring'
        template_values = {
            'greetings': greetings,
        }
        template = jinja_environment.get_template('index.html')
        self.response.out.write(template.render(template_values))

但我目前正在使用 Simpleauth(https://github.com/crhym3/simpleauth),它遵循尼克约翰逊在此处描述的实现:http: //blog.notdot.net/2011/11/Migrating-to-Python -2-7-part-2-Webapp-and-templates其中 jinja2 是从 webapp2_extras 导入的:

import os
import webapp2
from webapp2_extras import jinja2

class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

  def render_template(self, filename, **template_args):
        self.response.write(self.jinja2.render_template(filename, **template_args))

class IndexHandler(BaseHandler):
  def get(self):
    self.render_template('index.html', name=self.request.get('name'))

以下哪个是使用 jinja2 的首选方法?(他们似乎不能很好地一起玩,并且更愿意标准化最佳选择。)

4

4 回答 4

4

我有同样的问题,但这里的答案并不能让我满意。

我认为这是关于封装与性能。对于小型应用程序,您可以拥有全局,没问题。所以第一个解决方案很好。它让您以一种简单的方式解决一个简单的问题,而无需学习框架细节的开销。

对于更大的应用程序,您可能喜欢封装对象并将其引入对象。基本上,您创建了一个框架,一个可扩展性的基础设施。但这就是 webapp2 应该给你的。

其背后的基本问题:如果您决定将单例类型的对象作为逻辑的一部分实例化和释放的类(如官方示例中的 webapp2.RequestHandler 类),那么引用的对象(jinja2)将是当最后一个类实例消失时释放......你可能会得到很多释放和重新分配。因此,最好在某个地方(webapp2.registry)有一个对象的链接,以防止即使没有在其他任何地方引用也能被删除。它就像全局,但不会污染全局命名空间,并且可以通过 webapp2.get_app().registry 从任何地方访问它。它也是缓存。然后,使用 cached_property 你只做另一层缓存。

简而言之:如果你想封装你最好为你的应用程序添加缓存以保持效率

在这种情况下,您可以使用 webapp2_extra jinja2,并且在每个模块中,您都可以使用以下命令访问相同的 jinja 环境:

jinja2.get_jinja2().environment
于 2013-03-27T12:19:40.890 回答
3

我想他们几乎是一样的。webapp2_extras.jinja2 还做的是缓存 jinja2.Environment() 初始化(请求持续时间)。另外,您可以利用 webapp2 的配置/注册表系统。

查看get_jinja2() 源代码,您会发现它只是 jinja2.Environment() 的一个方便的包装器,带有一些默认环境参数和启用的扩展(例如 i18n)。

于 2012-10-23T08:11:17.303 回答
1

第一种方法是一个非常基本的例子。

第二种(使用 BaseHandler)是首选方法。在这里,您放置了 webapp2 共享方法。这些方法可以被派生类使用,在这里你可以放置你想要重写的 webapp2 方法,比如 dispatch。

于 2012-10-23T01:32:39.053 回答
1

TL;DR:使用选项 #2

如果你不使用 i18n,那也没关系。但在现实世界中,人们说的语言与英语不同,而且 GAE 上的 jinja2 i18n 存在一个棘手的问题:线程(即threadsafe: true在 app.yaml 中)默认开启并且对性能很重要,但是您可以找到的大多数 jinja2 i18n 文档在网络上不是线程安全的。由于您不想将语言环境显式传递给每个 jinja2 宏,因此需要将其保存在线程局部变量中。这是webapp2_extras.jinja2正确的做法。

于 2018-05-16T11:28:49.853 回答