【问题标题】:Flask Update paths upon deployment部署时的 Flask 更新路径
【发布时间】:2020-03-11 20:47:34
【问题描述】:

我一直在使用开发服务器开发一个烧瓶应用程序。现在我已经准备好将它部署到另一台机器上(上面已经有很多其他东西了),我正在学习如何使用 mod_wsgi 连接到 apache(它已经在服务器上运行)。我会就像我的整个烧瓶应用程序坐在像/mysite 这样的路径下。我知道我可以使用WSGIScriptAlias 来表示前缀,并在这个前缀路径之后发送烧瓶中的所有内容。

这对于使所有路由都按预期运行非常有效,但是我的 HTML/css/javascript 文件呢?如果我引用 HTML 文件中的路径,我是否必须更改它?或者有什么方法可以在全球范围内解决这个问题?

我担心我可能会进行大量重写...

谢谢, 杰克

【问题讨论】:

  • 如果有人想知道...我刚刚完成了所有的重写。这是一个相对较小的应用程序,所以它不是最糟糕的。不过,我仍然对找到更好的方法感到好奇。

标签: flask routes mod-wsgi wsgi


【解决方案1】:

蓝图允许您以非常模块化的方式构建您的应用程序,但还具有为每组路由声明特定 url 前缀的好处。这在大型应用程序中非常方便,因为您可以相对地指定您的路由路径,并且如果您的 url 结构发生变化,您不必更新所有路由,您只需更新前缀即可蓝图。我正在简化一点,但您可以阅读更多关于这种结构化应用程序模式的信息here

蓝图对较小的应用程序的真正好处是,如果您只有一个与您的应用程序关联的蓝图对象,您可以简单地为该蓝图声明 url 前缀,它会将前缀应用于您应用中的每条路线!

这里有一个非常简单的例子来展示这个概念

File structure

.
├── app.py
└── static
    └── index.js

index.js

console.log('hello from static!');

app.py

import os
from flask import Flask, Blueprint, jsonify, url_for
# there are a million ways to handle configuration,
# this is just for simplicity's sake for this example.
configuration = dict(
    development = dict(
        ENV='development',
        APPLICATION_ROOT='/',
    ),
    production=dict(
        ENV='production',
        APPLICATION_ROOT='/mysite/',
    ),
)
# get configuration based on environment
config_key = os.getenv('FLASK_CONFIG', 'development')
config_dict = configuration[config_key]
app = Flask(__name__, static_url_path=config_dict['APPLICATION_ROOT'])
app.config.update(config_dict)
bp = Blueprint('myapp', __name__)

@bp.route('/')
def index():
    return jsonify(message='hello from root!')

@bp.route('/foo')
def foo():
    path = url_for('static', filename='index.js')
    return jsonify(path=path)

# attach your routes to the application
app.register_blueprint(bp, url_prefix=app.config['APPLICATION_ROOT'])

if __name__ == '__main__':
    app.run()

与您可能习惯看到的最大变化是 - 我们使用@bp.route而不是@app.route,这样我们的路径可以自动设置为相对于我们的url前缀 - 我们必须采取额外的步骤app.register_blueprint() 以便 Flask 能够找到我们的路线(没有这个,你只会得到 404)

当我们运行python3 app.py(或flask run)并导航到常规根路由/时,我们会收到我们的消息。

localhost:5000

{"message": "hello from root!"}

当我们访问 /foo 路由时,我们会收到以下响应,告诉我们 javascript 文件的位置

localhost:5000/foo

{"path":"/index.js"}

在那里导航,我们确实看到了我们文件的内容

localhost:5000/index.js

console.log('hello from static!);

以前,由于我们没有设置环境变量FLASK_CONFIG,我们的应用默认使用我们的开发设置。现在让我们看看当我们设置该值时会发生什么,就像我们在生产环境中所做的那样

$ export FLASK_CONFIG=production

现在,导航到我们之前的根路由会返回 404,所以我们改为转到我们的生产 url 前缀

localhost:5000/mysite

{"message": "hello from root!"}

导航到我们的/foo 路由以查看我们的静态文件所在的位置

localhost:5000/mysite/foo

{"path":"/mysite/index.js"}

最后,导航到该路径实际上会显示我们的 javascript 文件

localhost:5000/mysite/index.js

console.log('hello from static!);

如果您希望在您的静态资产前加上其他内容作为 url 的一部分,甚至可能只是 /static/<your-file>,您所要做的就是更改 app.py 中的这一行

# from this
app = Flask(__name__, static_url_path=config_dict['APPLICATION_ROOT'])

# to this
app = Flask(__name__, static_url_path=config_dict['APPLICATION_ROOT']+'static/')

例如,现在您的路径将类似于 localhost:5000/static/index.js

最后,为了解决您对必须更改 HTML 文件中的路径的担忧:您可以使用与 foo 路由中演示的相同的 url_for() 函数来引用蓝图中的任何位置。诀窍是引用 路由的函数名,所以如果你想创建一个到foo() 的链接,你可以使用url_for('bp.foo'),其中'bp'Blueprint 中使用的字符串功能。

我知道这是很多信息,但是当我第一次学习时,我很难理解这个概念,所以我试图帮助其他人免于头痛。干杯!

【讨论】:

  • 感谢您的回答。非常全面。在阅读开始时,我认为它不会回答我的问题,但到最后我看到了它是如何做到的。这有点棘手!
猜你喜欢
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2014-01-05
  • 2012-06-08
  • 2011-06-11
  • 2015-07-21
相关资源
最近更新 更多