Установка переменной внутри запроса Flask с использованием промежуточного программного обеспечения для использования внутри шаблонов

#python #flask #wsgi

#python #flask #wsgi

Вопрос:

Основываясь на первой части пути, по которому осуществляется доступ к приложению, я хочу, чтобы приложение отображалось по-другому. Я попытался установить переменную в 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 %}
  

Ответ №1:

request Объект, созданный вами в промежуточном программном обеспечении, не имеет никакого отношения к request объекту, который создает Flask. 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 . Вы можете смоделировать это в dev с помощью Werkzeug DispatcherMiddleware .

 app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(app, {"/one": app, "/two": app})
  
 {% if request.script_root == "/one" %}