template example javascript python django

example - Pasar datos de Python a JavaScript a través de Django



django javascript integration (6)

Estoy usando Django y Apache para servir páginas web. Mi código JavaScript actualmente incluye un objeto de datos con valores que se mostrarán en varios widgets HTML basados ​​en la selección del usuario desde un menú de opciones. Quiero derivar estos datos de un diccionario de Python. Creo que sé cómo insertar el código JavaScript en el HTML, pero ¿cómo incrusto el objeto de datos en ese script (sobre la marcha) para que las funciones del script puedan usarlo?

Dicho de otra manera, quiero crear un objeto o matriz de JavaScript a partir de un diccionario de Python, luego insertar ese objeto en el código JavaScript y luego insertar ese código JavaScript en el HTML.

Supongo que esta estructura (por ejemplo, datos incrustados en variables en el código JavaScript) no es óptima, pero como novato no conozco las alternativas. He visto reportajes de las funciones de serialización de Django, pero estos no me ayudan hasta que puedo obtener los datos en mi código JavaScript en primer lugar.

No estoy (todavía) usando una biblioteca de JavaScript como jQuery.


Es subóptimo ¿Has considerado pasar tus datos como JSON utilizando el serializador integrado de django para eso?


Para cualquier persona que pueda estar teniendo problemas con esto, asegúrese de que esté renderizando su objeto JSON en modo seguro en la plantilla. Puede configurar esto manualmente de esta manera

<script type="text/javascript"> data_from_django = {{ my_data|safe }}; widget.init(data_from_django); </script>


Poner Java Script incrustado en la plantilla de Django es siempre una mala idea.

Más bien , porque hay algunas excepciones a esta regla.

Todo depende del sitio y la funcionalidad del código de Java Script.

Es mejor tener archivos separados estáticos, como JS, pero el problema es que cada archivo separado necesita otro mecanismo de conexión / GET / solicitud / respuesta. A veces, para uno pequeño, dos liners código OS JS para poner esto en plantilla, bollo y luego utilizar el mecanismo django templatetags - se puede utilizar es en otras plantillas;)

Acerca de los objetos, lo mismo. Si su sitio tiene AJAX construction / web2.0 como favor, puede lograr muy buenos resultados poniendo algo de operación de recuento / matemática en el lado del cliente. Si los objetos son pequeños, incrustados en la plantilla, si son grandes, respóndalos en otra conexión para evitar que el usuario se cuelgue la página.


Puede incluir etiquetas <script> dentro de sus plantillas .html, y luego construir sus estructuras de datos, sin embargo, es conveniente para usted. El lenguaje de plantilla no es solo para HTML, también puede hacer literales de objetos Javascript.

Y Paul tiene razón: podría ser mejor usar un módulo json para crear una cadena JSON, luego insertar esa cadena en la plantilla. Eso manejará mejor las cuestiones de cotización y tratará las estructuras profundas con facilidad.


Vea la respuesta relacionada a esta pregunta . Una opción es usar jsonpickle para serializar entre objetos Python y objetos JSON / Javascript. Envuelve simplejson y maneja cosas que normalmente no son aceptadas por simplejson.


nb ver actualización 2018 en la parte inferior

Recomiendo no poner mucho JavaScript en sus plantillas de Django; tiende a ser difícil de escribir y depurar, especialmente a medida que se expande su proyecto. En su lugar, intente escribir todo su JavaScript en un archivo de script separado que cargue su plantilla y simplemente incluya solo un objeto de datos JSON en la plantilla. Esto le permite hacer cosas como ejecutar toda su aplicación de JavaScript a través de algo como JSLint , minimizarlo , etc. y puede probarlo con un archivo HTML estático sin dependencias en su aplicación Django. Usar una biblioteca como simplejson también le ahorra el tiempo dedicado a escribir un tedioso código de serialización.

Si no está asumiendo que está compilando una aplicación AJAX, esto podría hacerse simplemente así:

En la vista:

from django.utils import simplejson def view(request, …): js_data = simplejson.dumps(my_dict) … render_template_to_response("my_template.html", {"my_data": js_data, …})

En la plantilla:

<script type="text/javascript"> data_from_django = {{ my_data }}; widget.init(data_from_django); </script>

Tenga en cuenta que el tipo de datos importa: si my_data es un número simple o una cadena de una fuente controlada que no contiene HTML, como una fecha formateada, no se requiere un manejo especial. Si es posible tener datos no confiables proporcionados por un usuario, tendrá que desinfectarlos utilizando algo así como los filtros de escape o escapejs y asegúrese de que su JavaScript maneje los datos de manera segura para evitar ataques de scripting entre sitios .

En cuanto a las fechas, es posible que también desee pensar en cómo se pasan las fechas. Casi siempre me resulta más fácil pasarlos como marcas de tiempo de Unix:

En Django:

time_t = time.mktime(my_date.timetuple())

En JavaScript, suponiendo que hayas hecho algo como time_t = {{ time_t }} con los resultados del fragmento de arriba:

my_date = new Date(); my_date.setTime(time_t*1000);

Finalmente, preste atención a UTC: querrá que las funciones de fecha de Pyjan y Django intercambien datos en UTC para evitar turbulencias respecto de la hora local del usuario.

EDITAR: Tenga en cuenta que setTime en javascript está en milisegundos mientras que la salida de time.mktime es segundos. Es por eso que tenemos que multiplicar por 1000

Actualización de 2018: todavía me gusta JSON para valores complejos, pero en la década intermedia la API de datos HTML5 ha logrado compatibilidad casi universal con el navegador y es muy conveniente para pasar valores simples (sin lista / dict), especialmente si desea tener CSS. las reglas se aplican en función de esos valores y no le importan las versiones no compatibles de Internet Explorer.

<div id="my-widget" data-view-mode="tabular">…</div> let myWidget = document.getElementById("my-widget"); console.log(myWidget.dataset.viewMode); // Prints tabular somethingElse.addEventListener(''click'', evt => { myWidget.dataset.viewMode = "list"; });

Esta es una forma sencilla de exponer datos a CSS si desea establecer el estado de vista inicial en su plantilla de Django y hacer que se actualice automáticamente cuando JavaScript actualice el atributo de data- . Utilizo esto para cosas como ocultar un widget de progreso hasta que el usuario seleccione algo para procesar o para mostrar / ocultar errores de manera condicional en resultados de búsqueda o incluso algo como mostrar un recuento de registros activo usando CSS como #some-element::after { content: attr(data-active-transfers); } #some-element::after { content: attr(data-active-transfers); } .