使用中间件在 Flask 请求中设置变量以在模板中使用
Setting a variable inside Flask request using Middleware to be used inside templates
根据访问应用程序的路径的第一部分,我希望应用程序以不同方式呈现。我尝试使用中间件在 request
上设置一个变量,然后在模板中访问它。我打印了一些调试信息,这些信息确实出现了,所以我知道中间件代码 运行,但是一旦我到达模板就没有设置值。如何在 Flask 中使用的中间件中设置变量?
from werkzeug.wrappers import Request
class NavMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
request = Request(environ)
print('path: %s, url: %s' % (request.path, request.url))
if request.path.startswith("/myapp"):
print("Here")
request.application = "Myapp"
environ['application'] = "Myapp"
return self.app(environ, start_response)
{% if request.application == "Myapp" %}
{% include 'navbar_myapp.html' %}
{% endif %}
您在中间件中创建的 request
对象与 Flask 构建的 request
对象没有关系。只有 environ
在 WSGI 层之间传递。中间件修改后续层看到的请求的正确方法是修改 environ
dict。您已完成该操作,因此您需要访问 request.environ
中的值,而不是 request
对象本身的值。
class NavMiddleware:
def __init__(self, app, app_name):
self.app = app
self.app_name = app_name
def __call__(self, environ, start_response):
request = Request(environ)
first_path = request.path.lstrip("/").partition("/")[0]
environ["nav_middleware.app_name"] = first_path
return self.app(environ, start_response)
app = Flask(__name__)
app.wsgi_app = NavMiddleware(app.wsgi_app, "my_app")
{% if request.environ["nav_middleware.app_name"] == "my_app" %}
这个答案一般适用于中间件,但在这种特殊情况下不需要中间件。 WSGI 服务器可以在不同的 SCRIPT_NAME
位置挂载应用程序,暴露为 request.script_root
。您可以使用 Werkzeug 的 DispatcherMiddleware
.
在 dev 中对此进行模拟
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(app, {"/one": app, "/two": app})
{% if request.script_root == "/one" %}
根据访问应用程序的路径的第一部分,我希望应用程序以不同方式呈现。我尝试使用中间件在 request
上设置一个变量,然后在模板中访问它。我打印了一些调试信息,这些信息确实出现了,所以我知道中间件代码 运行,但是一旦我到达模板就没有设置值。如何在 Flask 中使用的中间件中设置变量?
from werkzeug.wrappers import Request
class NavMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
request = Request(environ)
print('path: %s, url: %s' % (request.path, request.url))
if request.path.startswith("/myapp"):
print("Here")
request.application = "Myapp"
environ['application'] = "Myapp"
return self.app(environ, start_response)
{% if request.application == "Myapp" %}
{% include 'navbar_myapp.html' %}
{% endif %}
您在中间件中创建的 request
对象与 Flask 构建的 request
对象没有关系。只有 environ
在 WSGI 层之间传递。中间件修改后续层看到的请求的正确方法是修改 environ
dict。您已完成该操作,因此您需要访问 request.environ
中的值,而不是 request
对象本身的值。
class NavMiddleware:
def __init__(self, app, app_name):
self.app = app
self.app_name = app_name
def __call__(self, environ, start_response):
request = Request(environ)
first_path = request.path.lstrip("/").partition("/")[0]
environ["nav_middleware.app_name"] = first_path
return self.app(environ, start_response)
app = Flask(__name__)
app.wsgi_app = NavMiddleware(app.wsgi_app, "my_app")
{% if request.environ["nav_middleware.app_name"] == "my_app" %}
这个答案一般适用于中间件,但在这种特殊情况下不需要中间件。 WSGI 服务器可以在不同的 SCRIPT_NAME
位置挂载应用程序,暴露为 request.script_root
。您可以使用 Werkzeug 的 DispatcherMiddleware
.
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(app, {"/one": app, "/two": app})
{% if request.script_root == "/one" %}