Flask - 在另一个耗时的功能运行时显示加载页面

and*_*vua 4 html python flask

大家好。我正在开发我的第一个 Flask 项目,但遇到了以下问题:

我有一个简单的 Flask 应用程序:

from flask import Flask, render_template
import map_plotting_test as mpt

app = Flask(__name__)


@app.route('/')
def render_the_map():
    mpt.create_map()
    return render_template("map.html")


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

Run Code Online (Sandbox Code Playgroud)

问题

mpt.create_map()这里的功能只是制作地图,渲染它,然后创建map.html文件并将其保存到 templates 文件夹:templates/map.html。它工作得很好,但需要一些明显的时间才能完成地图的制作(大约 10-15 秒)。

问题是,当执行这个函数时,我在浏览器中只看到一个空白屏幕,然后 Flask 才会渲染完成的map.html文件。

我想要的是

create_map()我想要做的是在函数运行时显示加载屏幕而不是空白屏幕。当该函数完成其工作并创建一个 map.html 文件时,就像那样向用户显示渲染的模板return render_template("map.html")

有没有一种方法可以轻松实现这一目标?我是 Flask 的新手,如果有好的解释我将非常感激。

谢谢你!!!

and*_*vua 8

终于我找到了解决方案!

谢劳雷尔的回答。我会让它变得更加美好和清晰。

我做了什么

我重新设计了 Flask 应用程序,它看起来像这样:

from flask import Flask, render_template
import map_plotting_module as mpm

app = Flask(__name__)


@app.route('/')
def loading():
    return render_template("loading.html")


@app.route('/map')
def show_map():
    return render_template("map.html")


@app.route('/create_map')
def create_map():
    mpm.create_map()
    return "Map created"


if __name__ == '__main__':
    app.run()
Run Code Online (Sandbox Code Playgroud)

当用户打开页面时,Flask 会开始渲染文件loading.html。在此文件中,您必须将以下代码添加到该<head>部分:

<script>
    function navigate() {
        window.location.href = 'map';  // Redirects user to the /map route when 'create_map' is finished
    }
    fetch('create_map').then(navigate); // Performing 'create_map' and then calls navigate() function, declared above
</script>
Run Code Online (Sandbox Code Playgroud)

然后,将加载轮 div 添加到您的<body>部分:

<body>
    <div class="loader"></div>
</body>
Run Code Online (Sandbox Code Playgroud)

如果您仍然不清楚 - 请查看答案末尾我的示例

解释

在本<script>节中我们必须声明navigate()函数。/map在当前情况下,它只是将用户重定向到所需的参考。

fetch()是模拟jQuery.ajax()阅读更多。它只是将应用程序路由获取到/create_map,等待它在“后台”完成,然后在.then()块中执行操作 -navigate()在我们的例子中是函数。

所以工作流程是:

  1. 用户打开页面,@app.route('/')执行功能,即加载页面。
  2. 加载页面获取@app.route('/create_map')并在后台运行其功能。
  3. create_map()函数完成时 - 用户将被重定向到@app.route('/map')哪个函数正在渲染全部完成的map.html模板。

我的一些建议

  • 如果您希望加载页面有一个图标,只需将以下选项卡添加到您的<head>部分loading.html
<script>
    function navigate() {
        window.location.href = 'map';  // Redirects user to the /map route when 'create_map' is finished
    }
    fetch('create_map').then(navigate); // Performing 'create_map' and then calls navigate() function, declared above
</script>
Run Code Online (Sandbox Code Playgroud)

注意,Flask 正在文件夹中搜索媒体/static。将您的媒体放入其中。否则,媒体将不会被渲染!

  • 如果您希望加载页面有一个漂亮的 CSS 加载器,请考虑访问此页面:loading.io。我真的很喜欢它。

最后,这是作为加载器示例的代码片段:

<body>
    <div class="loader"></div>
</body>
Run Code Online (Sandbox Code Playgroud)
<link rel="icon" href="/static/<icon_file>">
Run Code Online (Sandbox Code Playgroud)