如何在模板中将数据从 Flask 传递到 JavaScript?

2022-08-30 02:40:10

我的应用调用返回字典的 API。我想将此命令中的信息传递给视图中的 JavaScript。我正在JS中使用Google Maps API,因此我想向它传递一个包含长/纬度信息的元组列表。我知道这会将这些变量传递给视图,以便它们可以在HTML中使用,但是我怎么能将它们传递给模板中的JavaScript呢?render_template

from flask import Flask
from flask import render_template

app = Flask(__name__)

import foo_api

api = foo_api.API('API KEY')

@app.route('/')
def get_data():
    events = api.call(get_event, arg0, arg1)
    geocode = event['latitude'], event['longitude']
    return render_template('get_data.html', geocode=geocode)

答案 1

您可以在模板中的任何位置使用,而不仅仅是在 HTML 部分。所以这应该有效:{{ variable }}

<html>
<head>
  <script>
    var someJavaScriptVar = '{{ geocode[1] }}';
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: {{ geocode[0] }} ' + someJavaScriptVar)" />
</body>
</html>

可以将其视为两个阶段的过程:首先,Jinja(Flask使用的模板引擎)生成文本输出。这将发送给执行他所看到的 JavaScript 的用户。如果您希望 Flask 变量在 JavaScript 中作为数组可用,则必须在输出中生成数组定义:

<html>
  <head>
    <script>
      var myGeocode = ['{{ geocode[0] }}', '{{ geocode[1] }}'];
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

Jinja还提供了来自Python的更高级的结构,因此您可以将其缩短为:

<html>
<head>
  <script>
    var myGeocode = [{{ ', '.join(geocode) }}];
  </script>
</head>
<body>
  <p>Hello World</p>
  <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
</body>
</html>

您还可以使用循环,语句等等,请参阅Jinja2文档了解更多信息。forif

另外,看看福特的回答,他指出了tojson过滤器,这是Jinja2标准过滤器集的补充

编辑2018年11月:tojson现在包含在Jinja2的标准过滤器集中。


答案 2

将几乎任何Python对象放入JavaScript对象的理想方法是使用JSON。JSON作为一种在系统之间传输的格式很棒,但有时我们忘记了它代表JavaScript Object Notation。这意味着将 JSON 注入模板与注入描述对象的 JavaScript 代码相同。

Flask为此提供了一个Jinja过滤器:tojson将结构转储到JSON字符串并将其标记为安全,以便Jinja不会自动交换它。

<html>
  <head>
    <script>
      var myGeocode = {{ geocode|tojson }};
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

这适用于 JSON 可序列化的任何 Python 结构:

python_data = {
    'some_list': [4, 5, 6],
    'nested_dict': {'foo': 7, 'bar': 'a string'}
}
var data = {{ python_data|tojson }};
alert('Data: ' + data.some_list[1] + ' ' + data.nested_dict.foo + 
      ' ' + data.nested_dict.bar);