Variables de plantilla Django y Javascript

Cuando renderizo una página usando el procesador de plantillas Django, puedo pasar una variable de diccionario que contiene varios valores para manipularlos en la página usando {{ myVar }} .

¿Hay alguna forma de acceder a la misma variable en Javascript (quizás utilizando el DOM, no sé cómo Django hace que las variables sean accesibles)? Quiero poder buscar detalles utilizando una búsqueda AJAX basada en los valores contenidos en las variables pasadas.

La {{variable}} se sustituye directamente en el HTML. Hacer una fuente de vista; no es una “variable” ni nada parecido. Es sólo un texto renderizado.

Dicho esto, puedes poner este tipo de sustitución en tu JavaScript.

  

Esto te da javascript “dynamic”.

PRECAUCIÓN Consulte el boleto número 17419 para conocer cómo agregar una etiqueta similar al núcleo de Django y las posibles vulnerabilidades de XSS introducidas al usar esta etiqueta de plantilla con datos generados por el usuario. El comentario de amacneil discute la mayoría de las preocupaciones planteadas en el boleto.


Creo que la forma más flexible y práctica de hacer esto es definir un filtro de plantilla para las variables que desea usar en el código JS. Esto le permite asegurarse de que sus datos se escapan correctamente y puede usarlos con estructuras de datos complejas, como dict y list . Por eso escribo esta respuesta a pesar de que hay una respuesta aceptada con muchos votos positivos.

Aquí hay un ejemplo de filtro de plantilla:

 // myapp/templatetags/js.py from django.utils.safestring import mark_safe from django.template import Library import json register = Library() @register.filter(is_safe=True) def js(obj): return mark_safe(json.dumps(obj)) 

Esta plantilla de filtros convierte la variable a cadena JSON. Puedes usarlo así:

 // myapp/templates/example.html {% load js %}  

Una solución que funcionó para mí es utilizar el campo de entrada oculto en la plantilla.

  

Entonces obteniendo el valor en javascript de esta manera,

 var myVar = document.getElementById("myVar").value; 

Para un diccionario, lo mejor es codificar a JSON primero. Puede usar simplejson.dumps () o si desea convertir un modelo de datos en App Engine, puede usar encode () de la biblioteca GQLEncoder.

Cuando Django devuelve la variable, todas las comillas se convierten en " . El uso de {{someDjangoVariable|safe}} provoca un error de Javascript.

Para solucionar esto usa Javascript .replace :

  

Esto es lo que hago muy fácilmente: modifiqué mi archivo base.html para mi plantilla y lo puse en la parte inferior:

 {% if DJdata %}  {% endif %} 

luego, cuando quiero usar una variable en los archivos javascript, creo un diccionario DJdata y lo agrego al contexto con un json: context['DJdata'] = json.dumps(DJdata)

¡Espero eso ayude!

Me enfrentaba a un problema similar y la respuesta sugerida por S.Lott funcionó para mí.

  

Sin embargo, me gustaría señalar las principales limitaciones de implementación aquí. Si planea poner su código javascript en un archivo diferente e incluir ese archivo en su plantilla. Esto no funcionará.

Esto funciona solo cuando la plantilla principal y el código javascript están en el mismo archivo. Probablemente el equipo de django pueda abordar esta limitación.

He estado luchando con esto también. En la superficie parece que las soluciones anteriores deberían funcionar. Sin embargo, la architecture django requiere que cada archivo html tenga sus propias variables renderizadas (es decir, {{contact}} se representa en contact.html , mientras que {{posts}} va a, por ejemplo, index.html y así sucesivamente). Por otro lado, las tags aparecen después de {%endblock%} en base.html de las que se heredan contact.html e index.html . Esto básicamente significa que cualquier solución incluyendo

  

está destinado a fallar, porque la variable y el script no pueden coexistir en el mismo archivo.

La solución simple que finalmente encontré, y trabajé para mí, fue simplemente envolver la variable con una etiqueta con id y luego referirla a ella en el archivo js, ​​así:

 // index.html 
{{ myVar }}

y entonces:

 // somecode.js var someVar = document.getElementById("myvar").innerHTML; 

y solo incluya en base.html como de costumbre. Por supuesto, esto es solo para obtener el contenido. Respecto a la seguridad, solo sigue las otras respuestas.

A partir de Django 2.1, se introdujo una nueva etiqueta de plantilla incorporada específicamente para este caso de uso: json_script .

https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#json-script .

La nueva etiqueta serializará de forma segura los valores de la plantilla y protegerá contra XSS.

Para un objeto JavaScript almacenado en un campo Django como texto, que debe convertirse nuevamente en un objeto JavaScript insertado dinámicamente en el script en la página, debe usar tanto escapejs como JSON.parse() :

 var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}"); 

El escapejs de Django maneja las escapejs correctamente, y JSON.parse() convierte la cadena de nuevo en un objeto JS.

Tenga en cuenta que si desea pasar una variable a un script .js externo, debe preceder a su etiqueta de script con otra etiqueta de script que declara una variable global.

   

data se definen en la vista de la forma habitual en get_context_data

 def get_context_data(self, *args, **kwargs): context['myVar'] = True return context