Каков предпочтительный метод использования jinja2 в App Engine?

Первоначально я реализовал Jinja2 в App Engine, используя примеры, показанные на сайте App Engine: 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? (Они, похоже, не играют вместе красиво и предпочитают стандартизировать лучший вариант.)

Ответ 1

Я думаю, они почти одинаковы. Что еще делает webapp2_extras.jinja2, так это то, что он кэширует инициализацию jinja2.Environment() (для длительности запроса). Кроме того, вы можете использовать конфигурацию/систему реестра webapp2.

Глядя на get_jinja2() source, вы увидите, что это просто удобная оболочка для jinja2.Environment() с некоторыми аргументами окружения по умолчанию и (например, i18n).

Ответ 2

У меня был тот же вопрос, но ответы здесь меня не удовлетворяют.

Я думаю об инкапсуляции и производительности. Для небольшого приложения у вас может быть глобальная проблема. Поэтому первое решение просто отлично. Это позволяет легко и легко решить легкую задачу, без накладных расходов, чтобы узнать подробности о структуре.

Для большего приложения вы, вероятно, хотите инкапсулировать и принести некоторый порядок в свои объекты. В основном вы создаете структуру, инфраструктуру для масштабируемости. Но то, что вам предлагает webapp2.

Основная проблема: Если вы решите сделать объект singleton типа локальным для класса, который получает instanciated и освобождается как часть логики (например, классы webapp2.RequestHandler в официальных примерах), то этот ссылочный объект (jinja2) будет выпущен, когда последний экземпляр класса не прошло... вы можете получить много свободного и перераспределения. Поэтому полезно иметь ссылку на объект где-нибудь (webapp2.registry), чтобы предотвратить удаление, даже если оно не упоминается нигде. Он похож на глобальный, но не обменивая глобальное пространство имен, и он доступен извне через webapp2.get_app(). Registry. Это также кеширование. Затем с помощью cached_property вы делаете еще один уровень кэширования.

Вкратце: если вы хотите инкапсулировать, вам лучше добавить кеширование для вашего приложения, чтобы оставаться эффективным

В этом случае вы переходите к webapp2_extra jinja2, и в каждом модуле вы можете получить доступ к той же среде jinja, что:

jinja2.get_jinja2().environment

Ответ 3

Первый метод - очень простой пример.

Второй (с BaseHandler) является предпочтительным методом. Здесь вы помещаете общие методы webapp2. Эти методы могут использоваться производными классами, и здесь вы помещаете методы webapp2, которые вы хотите переопределить как отправка.