¿Cómo puedo pasar datos de Flask a JavaScript en una plantilla?
python jinja2 (6)
Algunos archivos js provienen de la web o la biblioteca, no están escritos por usted mismo. El código tienen una variable como esta:
var queryString = document.location.search.substring(1);
var params = PDFViewerApplication.parseQueryString(queryString);
var file = ''file'' in params ? params.file : DEFAULT_URL;
Este método hace que los archivos js no se modifiquen (mantener la independencia), ¡y pasa la variable correctamente!
Mi aplicación hace una llamada a una API que devuelve un diccionario. Quiero pasar información de este dict a JavaScript en la vista. Estoy usando la API de Google Maps en el JS, específicamente, así que me gustaría pasarle una lista de tuplas con la información larga / lat. Sé que render_template
pasará estas variables a la vista para que puedan usarse en HTML, pero ¿cómo podría pasarlas a JavaScript en la plantilla?
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)
Alternativamente, puede agregar un punto final para devolver su variable:
@app.route("/api/geocode")
def geo_code():
return jsonify(geocode)
Luego haz un XHR para recuperarlo:
fetch(''/api/geocode'')
.then((res)=>{ console.log(res) })
El uso de un atributo de datos en un elemento HTML evita tener que usar scripts en línea, lo que a su vez significa que puede usar reglas CSP más estrictas para aumentar la seguridad.
Especifique un atributo de datos como ese:
<div id="mydiv" data-geocode="{{ geocode|tojson }}">...</div>
A continuación, acceda a él en un archivo JavaScript estático como ese:
// Raw JavaScript
var geocode = JSON.parse(document.getElementById("mydiv").dataset.geocode);
// jQuery
var geocode = JSON.parse($("#mydiv").data("geocode"));
La forma ideal de obtener casi cualquier objeto Python en un objeto JavaScript es usar JSON. JSON es genial como un formato para la transferencia entre sistemas, pero a veces nos olvidamos de que representa la notación de objetos de JavaScript. Esto significa que inyectar JSON en la plantilla es lo mismo que inyectar código JavaScript que describe el objeto.
Flask proporciona un filtro Jinja para esto: tojson
vuelca la estructura a una cadena JSON y la marca de forma segura para que Jinja no la escape automáticamente.
<html>
<head>
<script>
var myGeocode = {{ geocode|tojson }};
</script>
</head>
<body>
<p>Hello World</p>
<button onclick="alert(''Geocode: '' + myGeocode[0] + '' '' + myGeocode[1])" />
</body>
</html>
Esto funciona para cualquier estructura Python que sea serializable JSON:
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);
Puede usar {{ variable }}
en cualquier lugar de su plantilla, no solo en la parte HTML. Entonces esto debería funcionar:
<html>
<head>
<script>
var someJavaScriptVar = ''{{ geocode[1] }}'';
</script>
<body>
<p>Hello World</p>
<button onclick="alert(''Geocode: {{ geocode[0] }} '' + someJavaScriptVar)" />
</body>
</html>
Piense en ello como un proceso de dos etapas: primero, Jinja (el motor de plantilla que utiliza Flask) genera su salida de texto. Esto se envía al usuario que ejecuta el JavaScript que ve. Si desea que su variable Flask esté disponible en JavaScript como una matriz, debe generar una definición de matriz en su resultado:
<html>
<head>
<script>
var myGeocode = [''{{ geocode[0] }}'', ''{{ geocode[1] }}''];
</script>
<body>
<p>Hello World</p>
<button onclick="alert(''Geocode: '' + myGeocode[0] + '' '' + myGeocode[1])" />
</body>
</html>
Jinja también ofrece construcciones más avanzadas de Python, por lo que puedes acortarlo a:
<html>
<head>
<script>
var myGeocode = [{{ '', ''.join(geocode) }}];
</script>
<body>
<p>Hello World</p>
<button onclick="alert(''Geocode: '' + myGeocode[0] + '' '' + myGeocode[1])" />
</body>
</html>
También puede utilizar for
bucles for
, declaraciones if
y muchas más, consulte la documentación de Jinja2 para obtener más información.
También eche un vistazo a la respuesta de ford que señala el filtro tojson
que es una adición al conjunto estándar de filtros de Jinja2 .
Solo otra solución alternativa para aquellos que quieren pasar variables a un script que se obtiene utilizando un matraz, solo logré que esto funcionara definiendo las variables afuera y luego llamando al script de la siguiente manera:
<script>
var myfileuri = "/static/my_csv.csv"
var mytableid = ''mytable'';
</script>
<script type="text/javascript" src="/static/test123.js"></script>
Si ingreso variables jinja en test123.js
no funciona y obtendrá un error.