Domanda

Quando eseguo il rendering di una pagina utilizzando il renderer modello Django, posso passare una variabile del dizionario contenente vari valori per manipolarli nella pagina utilizzando {{ myVar }}.

C'è un modo per accedere alla stessa variabile in Javascript (forse usando il DOM, non so come Django renda accessibili le variabili)? Voglio essere in grado di cercare i dettagli utilizzando una ricerca AJAX basata sui valori contenuti nelle variabili trasmesse.

È stato utile?

Soluzione

Il {{variable}} viene sostituito direttamente nell'HTML. Fare una vista sorgente; non è una " variabile " o qualcosa del genere. È solo testo renderizzato.

Detto questo, puoi inserire questo tipo di sostituzione nel tuo JavaScript.

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}";
</script>

Questo ti dà " dinamico " javascript.

Altri suggerimenti

ATTENZIONE Controlla il biglietto # 17419 per la discussione sull'aggiunta di tag simili nel core di Django e possibili vulnerabilità XSS introdotte utilizzando questo tag template con i dati generati dall'utente. Comment di amacneil discute la maggior parte delle preoccupazioni sollevate nel biglietto.


Penso che il modo più flessibile e pratico per farlo sia quello di definire un filtro template per le variabili che vuoi usare nel codice JS. Ciò consente di garantire che i dati vengano salvati correttamente e che sia possibile utilizzarli con strutture dati complesse, come dict e list. Ecco perché scrivo questa risposta nonostante ci sia una risposta accettata con molti voti.

Ecco un esempio di filtro modello:

// 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))

Questo modello di filtri converte la variabile in stringa JSON. Puoi usarlo in questo modo:

// myapp/templates/example.html

{% load js %}

<script type="text/javascript">
    var someVar = {{ some_var | js }};
</script>

Una soluzione che ha funzionato per me sta usando il campo di input nascosto nel modello

<input type="hidden" id="myVar" name="variable" value="{{ variable }}">

Quindi ottenere il valore in javascript in questo modo,

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

Quando la variabile viene restituita da Django, trasforma tutte le virgolette in &quot;. L'uso di {{someDjangoVariable|safe}} provoca un errore Javascript.

Per risolvere questo problema, utilizzare Javascript .replace:

<script type="text/javascript"> 
    var json = "{{someDjangoVariable}}".replace(/&quot;/g,"\"")
</script>

Per un dizionario, è meglio prima codificare in JSON. È possibile utilizzare simplejson.dumps () o se si desidera convertire da un modello di dati in App Engine, è possibile utilizzare encode () dalla libreria GQLEncoder.

A partire da Django 2.1, un nuovo tag modello incorporato è stato introdotto appositamente per questo caso d'uso: json_script.

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

Il nuovo tag serializzerà in modo sicuro i valori dei modelli e protegge da XSS.

Ecco cosa sto facendo molto facilmente: Ho modificato il mio file base.html per il mio modello e l'ho messo in fondo:

{% if DJdata %}
    <script type="text/javascript">
        (function () {window.DJdata = {{DJdata|safe}};})();
    </script>
{% endif %}

quindi quando voglio usare una variabile nei file javascript, creo un dizionario DJdata e lo aggiungo al contesto da un json: context['DJdata'] = json.dumps(DJdata)

Spero che sia d'aiuto!

Stavo affrontando un problema simile e la risposta suggerita da S.Lott ha funzionato per me.

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}"
</script>

Tuttavia, vorrei evidenziare qui importanti limiti di implementazione . Se stai pianificando di inserire il tuo codice javascript in un altro file e includerlo nel tuo modello. Questo non funzionerà.

Funziona solo quando il modello principale e il codice javascript si trovano nello stesso file. Probabilmente il team Django può affrontare questa limitazione.

Ho avuto difficoltà anche con questo. A prima vista sembra che le soluzioni di cui sopra dovrebbero funzionare. Tuttavia, l'architettura django richiede che ogni file html abbia le proprie variabili renderizzate (ovvero, {{contact}} viene renderizzato in contact.html, mentre {{posts}} va ad es. index.html e così via). D'altra parte, i tag <script> compaiono dopo il {%endblock%} in base.html da cui <script src="static/js/somecode.js"></script> e <=> ereditano. Ciò significa sostanzialmente che qualsiasi soluzione, tra cui

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

è destinato a fallire, perché la variabile e lo script non possono coesistere nello stesso file.

La semplice soluzione che alla fine mi è venuta in mente, e ha funzionato per me, è stata semplicemente di avvolgere la variabile con un tag con id e successivamente riferirla ad essa nel file js, in questo modo:

// index.html
<div id="myvar">{{ myVar }}</div>

e quindi:

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

e includi <=> in <=> come al solito. Ovviamente si tratta solo di ottenere il contenuto. Per quanto riguarda la sicurezza, basta seguire le altre risposte.

Per un oggetto JavaScript memorizzato in un campo Django come testo, che deve diventare nuovamente un oggetto JavaScript inserito dinamicamente nello script on-page, è necessario utilizzare sia escapejs che JSON.parse():

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

Django <=> gestisce correttamente le quotazioni e <=> converte nuovamente la stringa in un oggetto JS.

Nota, se vuoi passare una variabile a uno script .js esterno, devi precedere il tuo tag di script con un altro tag di script che dichiara una variabile globale.

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

<script type="text/javascript" src="{% static "scripts/my_script.js" %}"></script>

data è definito nella vista come al solito in get_context_data

def get_context_data(self, *args, **kwargs):
    context['myVar'] = True
    return context
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top