Werkzeug 및 Jinja2를 사용한 컨텍스트 프로세서
-
22-08-2019 - |
해결책
이것을 달성하는 한 가지 방법은 늦은 부분을 통하는 것입니다 템플릿 글로벌 사용 스레드-로컬 프록시 Werkzeug에서.
요청을 템플릿 글로벌에 넣는 간단한 예 :
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)
이제 모든 템플릿에서 현재 요청이 변수 "요청"에 바인딩됩니다. 물론 그것은 환경에서 다른 일이 될 수 있습니다. 트릭은 로컬 프록시를 사용한 다음 템플릿을 렌더링하기 전에 값을 설정하는 것입니다.
아마도 프레임 워크와 같은 것을 추가해야 할 것입니다 Glashammer (Werkzeug+Jinja2) 이벤트를 사용 하여이 프로세스를 간소화합니다. 많은 기능이 WSGI 호출 과정에서 이벤트에 연결할 수 있으며 (예 : 요청이 생성 될 때) 해당 시점에서 템플릿 네임 스페이스에 물건을 넣을 수 있습니다.
다른 팁
글쎄, 사용 알리가 쓴 것 나는 앱 엔진에 특정한 솔루션 (가져 오기 캐시 때문에)에 왔습니다. 불행히도 Ali의 코드는 Jinja Globals를 설정하는 코드가 한 번만 가져 오기 때문에 App Engine에서는 작동하지 않습니다 (글로벌을 효과적으로 정적으로 만들면).
나는 내 자신을 써야했다 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 특정입니다. 다른 환경에서 Ali의 코드는 예상대로 작동합니다 (그래서 제가 질문을 다시 시작하는 이유).
제휴하지 않습니다 StackOverflow