是否可以在服务器端的 Flask 中动态更新呈现的模板?
Posted
技术标签:
【中文标题】是否可以在服务器端的 Flask 中动态更新呈现的模板?【英文标题】:Is it possible to dynamically update a rendered template in Flask, server-side? 【发布时间】:2014-12-19 14:22:42 【问题描述】:我目前有一个 Flask Web 服务器,它使用内置的 requests 对象从 JSON API 中提取数据。
例如:
def get_data():
response = requests.get("http://myhost/jsonapi")
...
return response
@main.route("/", methods=["GET"])
def index():
return render_template("index.html", response=response)
这里的问题是 GET 方法自然只运行一次,即第一次调用 get_data。为了刷新数据,我必须停止并重新启动 Flask wsgi 服务器。我曾尝试在 while True / sleep 循环中包装代码的各个部分,但这会阻止 werkzeug 加载页面。
在无需重新加载页面或重新启动服务器的情况下动态获取所需数据的最 Pythonic 方式是什么?
【问题讨论】:
如果您愿意将get_data()
方法路由到 URL,您可以使用 AJAX 从客户端调用它并使用结果更新页面。
@Celeo 这是一种方式。但是假设我在一个单独的文件中有get_data()
,我不想添加另一条路线?我的问题是关于这是否可以使用 Flask 或 Flask 扩展来完成。
在服务器已经呈现模板之后,您必须有一些方法让客户端从服务器获取数据。如果您只想在没有客户端交互的情况下在后台更新数据,您可以尝试Celery。
谢谢,我应该补充一点,我为这个特定场景选择的后台任务管理器是RQ。
【参考方案1】:
您正在讨论可能是两个不同的问题。
假设问题是您只调用了一次动态数据源get_data()
,并将其(静态)值保存在全局response
中。这个一次性调用没有显示,但假设它在您的代码中的某个位置。然后,如果您愿意刷新页面 (/
) 以获取更新,您可以:
@main.route("/", methods=['GET'])
def index():
return render_template("index.html", response=get_data())
这将在每次页面加载时获取新数据。
然后在您的问题即将结束时,您询问如何“获取我想要的数据,而无需重新加载页面或重新启动服务器”。那是一个完全不同的问题。您必须在代码中使用 AJAX 或 WebSocket 请求。您可以通过谷歌搜索“Flask AJAX”找到很多关于如何执行此操作的教程(例如这个)。但这需要 javascript AJAX 调用。我建议通过搜索“Flask AJAX jQuery”来查找如何完成此操作的示例,因为 jQuery 将抽象和简化您需要在客户端执行的操作。或者,如果您希望使用 WebSockets 在您的网页之间进行低延迟连接,这也是可能的;搜索示例(例如like this one)。
【讨论】:
关于分成两个问题的好点。这既回答了我的具体情况,也回答了一般问题。可能也值得在这里分享Flask-SocketIO。 在您的回答中,您提到 一次性调用未显示...在 Python 代码中该一次性调用会是什么样子? @RussellBurdt OP 有一个get_data()
函数,后来有return render_template("index.html", response=response)
。大概有一个全局response = get_data()
未显示的地方;需要使该示例正常工作。我的建议基本上是将函数调用移动到路由处理程序中,这样每个请求都会调用它,而不仅仅是每次程序运行时静态调用一次。【参考方案2】:
添加到 Jonathan 的评论中,您可以使用诸如刺激或涡轮链接之类的框架来动态地执行此操作,而在某些情况下无需编写 JavaScript,因为框架会承担很多繁重的工作。 https://stimulus.hotwired.dev/handbook/origin
【讨论】:
以上是关于是否可以在服务器端的 Flask 中动态更新呈现的模板?的主要内容,如果未能解决你的问题,请参考以下文章
如果我不清除缓存,为啥我的 Flask 应用程序不呈现 CSS?
如果返回的数据已更改,则使用 Flask 轮询 API 并更新网页