Вопрос

Мое приложение работает на App Engine и реализовано с использованием Веркцойг и Джинджа2.Я хотел бы иметь что-то функционально эквивалентное собственному контекстному процессору Django:вызываемый объект, который принимает запрос и добавляет что-то в контекст шаблона.У меня уже есть «обработчики контекста», которые добавляют что-то в контекст шаблона, но как мне это получить? запрос часть работает?Я реализовал процессоры контекста как вызываемые объекты, которые просто возвращают словарь, который позже используется для обновления контекста.

Например, я хотел бы добавить что-то, что содержится в request.environ.

Это было полезно?

Решение

Один из способов добиться этого – поздняя привязка Глобальные переменные шаблона используя локальный прокси потока в Веркцойге.

Простой пример помещения запроса в глобальные переменные шаблона:

from werkzeug import Local, LocalManager
local = Local()
local_manager = LocalManager([local])

from jinja2 import Environment, FileSystemLoader

# Create a global dict using the local's proxy to the request attribute
global_dict = {'request': local('request')}
jinja2_env = Environment(loader=FileSystemLoader('/'))
jinja2_env.globals.update(global_dict)

def application(environ, start_response):
    """A WSGI Application"""
    # later, bind the actual attribute to the local object
    local.request = request = Request(environ)

    # continue to view handling code
    # ...

application = local_manager.make_middleware(application)

Теперь в любом из ваших шаблонов текущий запрос будет привязан к переменной «request».Конечно, это может быть что угодно в окружающей среде.Хитрость заключается в том, чтобы использовать локальный прокси, а затем установить значение перед визуализацией любого шаблона.

Вероятно, мне следует также добавить, что такая структура, как Гласхаммер (Werkzeug+Jinja2) упрощает этот процесс с помощью событий.Многие функции могут подключаться к событиям во время процесса вызова WSGI (например, при создании запроса) и в этот момент помещать данные в пространство имен шаблона.

Другие советы

Ну, используя что написал Али Я пришел к решению, специфичному для App Engine (из-за его кеша импорта).К сожалению, код Али не работает с App Engine, поскольку код, устанавливающий глобальные переменные Jinja, импортируется только один раз (что делает глобальные переменные фактически статичными).

мне пришлось написать свой собственный render() функцию и обновите там контекст.Для полноты картины ниже приведен код, к которому я пришел:

def render(template, **kwargs):
    response_code = kwargs.pop('response_code', 200)
    mimetype = kwargs.pop('mimetype', 'text/html')
    for item in getattr(settings, 'CONTEXT_PROCESSORS', []):
        try:
            processor = import_string(item)
            kwargs.update(processor(local.request))
        except (ImportError, AttributeError), e:
            logging.error(e)
    return Response(jinja_env.get_template(template).render(**kwargs),
        status=response_code, mimetype=mimetype)

Это особенность App Engine.В других средах код Али работает так, как ожидалось (именно поэтому я меняю свой вопрос).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top