2009-09-18 69 views
46

Estoy usando Django y Apache para dar servicio a 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?Pasar datos de Python a JavaScript a través de Django

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 código HTML.

Supongo que esta estructura (por ejemplo, los datos incrustados en variables en el código JavaScript) es subó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) utilizando una biblioteca JavaScript como jQuery.

+0

duplicado Posible [Variables de plantillas de Django y Javascript] (http://stackoverflow.com/questions/298772/django-template-variables-and-javascript) –

Respuesta

69

Te recomiendo no poner mucho JavaScript en tus plantillas de Django; tiende a ser difícil de escribir y depurar, especialmente a medida que tu proyecto se expande. 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 usted está construyendo una aplicación AJAX esto simplemente podría hacerse 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. re. Si es posible tener datos no confiables proporcionados por un usuario, tendrá que desinfectarlos usando algo como los filtros escape o escapejs y asegúrese de que su JavaScript maneje los datos de forma segura para evitar los ataques cross-site scripting.

En lo que respecta a las fechas, es posible que también desee pensar en cómo pasar las fechas.Casi siempre me he encontrado que es más fácil de pasar a ellos como marcas de tiempo Unix:

En Django:

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

En JavaScript, asumiendo que has hecho algo así como time_t = {{ time_t }} con los resultados del fragmento anterior:

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

por último, prestar atención a UTC - usted quiere tener los datos de cambio de funciones de fecha Python y Django en UTC para evitar cambios embarazosos de la hora local del usuario.

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

+0

Gracias. Planeé servir el javascript como un archivo multimedia, similar a una hoja de estilo css. Esto parece una solución mejor que integrar los datos en el js, aunque tendré que aprender algo de JSON y escribir algún código del lado del servidor para manejar las solicitudes de datos. – chernevik

+0

Suena como una buena idea. Una cosa que realmente me gusta de este enfoque es que es trivial escribir una vista de Django que devuelva JSON (si haces esto a menudo, mira django-piston para crear API REST) ​​y es muy fácil prueba partes aisladas de esa manera. –

+0

¡No estoy ignorando esto! Estoy mejorando mi conocimiento de escribir y servir Javascript hasta el punto en que realmente lo uso. Ahora planeo usar JSON para pasar los metadatos para determinar qué widgets se ven afectados por la elección del menú, pero esto me ha requerido más información sobre cómo crear y acceder a las estructuras de datos de JavaScript. – chernevik

2

No es óptimo. ¿Has considerado pasar tus datos como JSON utilizando el serializador integrado de django para eso?

+0

pensé Aprendería algunos conceptos básicos antes de meterse en las siglas. Pero parece que puedo aprender algo de JSON, o crear una solución a partir de elementos básicos, que eliminaré una vez que haya aprendido algo de JSON. – chernevik

3

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 inserte esa cadena en la plantilla. Eso manejará mejor las cuestiones de cotización y tratará las estructuras profundas con facilidad.

1

Consulte la respuesta relacionada con this question. 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.

1

Poner Java Script incrustado en la plantilla de Django es en lugar de siempre es 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 estáticos por separado, como JS, pero el problema es que cada archivo por 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 usar django templatetags mecanismo; puede usar está 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.

+0

Sí, y tienes json incorporado en django;) Olvídate de xml: P – bluszcz

34

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 manualmente este como esto

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