Flask {{request.script_root | tojson | safe}}没有返回值

时间:2015-10-24 12:17:21

标签: python flask jinja2

我正在关注其中一个基本的Flask教程,其中{{ request.script_root|tojson|safe }} Jinja2模板调用应该返回应用程序的基础根据(根据Flask docs here)。

我有一个 super 基本脚本设置如下:

# app/__init__.py

from flask import Flask

# import blueprints
from .views.index import index_blueprint

# create flask app
app = Flask(__name__)

app.register_blueprint(index_blueprint)

这是我的Blueprint

# app/views/index.py

from flask import Blueprint, render_template

index_blueprint = Blueprint('index_blueprint', __name__)

@index_blueprint.route('/')
def route_index():
    return render_template('index.html')

最后,我的index.html模板(位于template文件夹中:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>

    <script type="text/javascript">

        var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};

    </script>

</head>
<body>

    <p>Flask test.</p>

</body>
</html>

渲染后,$SCRIPT_ROOT应包含脚本根,或至少包含非空字符串。但是,生成的填充模板包含空字符串:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>

    <script type="text/javascript">

        var $SCRIPT_ROOT = "";

    </script>

</head>
<body>

    <p>Flask test.</p>

</body>
</html>

问题是为什么{{ request.script_root|tojson|safe }}会返回一个空字符串?

2 个答案:

答案 0 :(得分:3)

我假设您使用的是Flask的WSGI。在这种情况下,Flask不知道SCRIPT_NAME env变量,因为通常是HTTP服务器的工作来设置SCRIPT_NAME(以及PATH_INFO)。

Flask使用此env var(来自Request类的相关函数)设置script_root属性:

@cached_property
def script_root(self):
    """The root path of the script without the trailing slash."""
    raw_path = wsgi_decoding_dance(self.environ.get('SCRIPT_NAME') or '',
                                   self.charset, self.encoding_errors)
    return raw_path.rstrip('/')

如果您想手动设置,可以使用中间件(来自this snippet)实现此目的:

class AppMiddleware(object):
    def __init__(self, app, script_name=''):
        self.app = app
        self.script_name = script_name

    def __call__(self, environ, start_response):
        script_name = self.script_name
        if self.script_name:
            environ['SCRIPT_NAME'] = script_name
            path_info = environ['PATH_INFO']
            if path_info.startswith(script_name):
                environ['PATH_INFO'] = path_info[len(script_name):]

        return self.app(environ, start_response)

app = Flask(__name__)
app.wsgi_app = AppMiddleware(app.wsgi_app, '/myapp')

在此之后,{{ request.script_root }}将在您的模板中为/myapp

答案 1 :(得分:-1)

来自真实的doc

  

一个简单的方法是在我们的页面中添加一个脚本标记,将全局变量设置为应用程序根目录的前缀。像这样:

<script type=text/javascript>
  $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>

这项工作对我来说,只是在没有var =

的情况下添加此标记