Frage

Meine Anwendung auf App Engine ausgeführt wird, und ist unter Verwendung Werkzeug und Jinja2 . Ich möchte etwas funktional äquivalent von Djangos eigenen Kontext Prozessor haben: eine aufrufbar, die eine Anforderung nimmt und fügt etwas an der Vorlage Kontext. Ich habe bereits ein „Kontext-Prozessoren“, die etwas zu der Vorlage Kontext hinzufügen, aber wie bekomme ich diese Anfrage Teil zu arbeiten? Ich implementierte Kontext Prozessoren als Callables, die nur ein Wörterbuch zurück, die später verwendet wird, Kontext zu aktualisieren.

Zum Beispiel, ich möchte etwas hinzufügen, die in request.environ enthalten ist.

War es hilfreich?

Lösung

Eine Möglichkeit, dies zu erreichen, ist durch spät gebundene Vorlage Globals mit dem faden lokalen Proxy in Werkzeug rel="nofollow.

Ein einfaches Beispiel, das die Anforderung in der der Vorlage Globals setzt:

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)

Jetzt in Ihren Vorlagen, wird die aktuelle Anforderung an die Variable „Anfrage“ erscheint gebunden. Natürlich ist das alles andere in environ sein könnte. Der Trick ist, die lokale Proxy zu verwenden, dann wird der Wert eingestellt, bevor Sie eine Vorlage machen.

Ich sollte wohl auch hinzufügen, dass ein Framework wie Glashammer (Werkzeug + Jinja2) für Sie diesen Prozess rationalisiert durch Veranstaltungen mit . Viele Funktionen können während des Prozesses des WSGI Anruf (zum Beispiel, wenn eine Anforderung erstellt wird) zu den Ereignissen verbinden und sie können an diesem Punkt Sachen in der Vorlage-Namensraum setzen.

Andere Tipps

Nun, was Ali schrieb Ich kam zu die Lösung, die auf App Engine (wegen seiner Import-Cache) spezifisch ist. Leider hat Alis Code nicht mit App Engine arbeiten, da der Code, Jinja Globals setzt nur einmal importiert werden (die Globals effektiv statisch zu machen).

Ich hatte meine eigene render() Funktion zu schreiben und den Kontext dort zu aktualisieren. Der Vollständigkeit halber, unten ist der Code, den ich wieder zu mir kam:

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)

Dies ist App Engine spezifisch. In anderen Umgebungen Alis Code wie erwartet funktioniert (und das ist, warum ich meine Frage bin mit neuen Tags versehen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top