Pregunta

Mi aplicación se ejecuta en App Engine y se implementa utilizando Werkzeug y Jinja2. Me gustaría tener algo funcionalmente equivalente de un procesador propio contexto de Django: un invocable que toma una petición y añade algo al contexto de la plantilla. Ya tengo un "procesadores de contexto" que añaden algo al contexto de la plantilla, pero ¿cómo puedo obtener esta solicitud parte de trabajo? He implementado procesadores de contexto como callables que acaba de regresar de un diccionario que luego se utiliza para actualizar el contexto.

Por ejemplo, me gustaría añadir algo que se contiene en request.environ.

¿Fue útil?

Solución

Una forma de lograr esto es a través tardío unido plantilla globales usando el subproceso local de proxy en Werkzeug.

Un ejemplo sencillo que pone la solicitud en los las variables globales plantilla:

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)

Ahora bien, en cualquiera de sus plantillas, la petición actual aparecerá con destino a la "solicitud" variable. Por supuesto que podría ser cualquier otra cosa en Environ. El truco es usar el proxy local, a continuación, establecer el valor antes de dibujar cualquier plantilla.

Probablemente debería también añadir que un marco como Glashammer (Werkzeug + Jinja2) agiliza este proceso para que mediante el uso de eventos . Muchas funciones se pueden conectar a los eventos durante el proceso de la llamada WSGI (por ejemplo, cuando se crea una petición) y que pueden poner cosas en la zona de plantillas en ese punto.

Otros consejos

Bueno, usando lo escribió Ali llegué a la solución que es específico de App Engine (debido a su caché de importación). Por desgracia, el código de Ali no funciona con App Engine, debido a que el código que establece globales Jinja se importan sólo una vez (haciendo efectivamente las variables globales estáticos).

que tenía que escribir mi propia función render() y actualizar el contexto allí. Para completarlo, a continuación es el código que vine 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)

Esto es específico de App Engine. En otros entornos de código de Ali funciona como se esperaba (y por eso estoy reetiquetado mi pregunta).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top