Pergunta

A minha aplicação está em execução no App Engine e é implementado utilizando Werkzeug e Jinja2 . Eu gostaria de ter algo funcionalmente equivalente próprio processador contexto do Django: a função que recebe um pedido e acrescenta algo ao contexto do template. Eu já tenho um "processadores de contexto" que acrescentar algo ao contexto modelo, mas como faço para obter este pedido parte de trabalho? Eu implementei processadores contexto como uma chamáveis ??que apenas retornar um dicionário que depois é usado para o contexto de atualização.

Por exemplo, eu gostaria de acrescentar algo que está contido no request.environ.

Foi útil?

Solução

Uma maneira de conseguir isso é através de ligação tardia modelo globals utilizando a segmento local procuração em Werkzeug.

Um exemplo simples que coloca o pedido nos os globals de modelo:

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)

Agora, em qualquer um dos seus modelos, o pedido atual aparecerá vinculado à variável "pedido". Claro que poderia ser qualquer outra coisa em environ. O truque é usar o proxy local, em seguida, definir o valor antes de prestar qualquer modelo.

Eu provavelmente deve acrescentar também que um quadro como Glashammer (Werkzeug + Jinja2) agiliza esse processo para você, usando eventos . Muitas funções podem se conectar aos eventos durante o processo da chamada WSGI (por exemplo, quando um pedido é criado) e eles podem colocar coisas no namespace template naquele ponto.

Outras dicas

Bem, usando que Ali escreveu Eu vim para a solução que é específica para o App Engine (por causa de seu cache de importação). Infelizmente, o código de Ali não funciona com o Google App Engine, porque o código que define globals Jinja são importados apenas uma vez (fazer os globals efetivamente estático).

Eu tive que escrever minha própria função render() e atualizar o contexto lá. Para sermos mais completos, abaixo está o código que veio a:

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)

Esta é App Engine específico. Em outros ambientes código de Ali funciona como esperado (e é por isso que eu estou substituição de marcas auriculares a minha pergunta).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top