Lorsque je rends une page à l'aide du rendu de modèle Django, je peux passer une variable de dictionnaire contenant diverses valeurs pour les manipuler dans la page à l'aide {{ myVar }}
.
Existe-t-il un moyen d'accéder à la même variable en Javascript (peut-être en utilisant le DOM, je ne sais pas comment Django rend les variables accessibles)? Je veux pouvoir rechercher des détails en utilisant une recherche AJAX basée sur les valeurs contenues dans les variables transmises.
escapejs
filtre existe:escapejs('<>') -> u'\\u003C\\u003E'
ATTENTION Consultez le ticket # 17419 pour une discussion sur l'ajout d'une balise similaire dans le noyau Django et les vulnérabilités XSS possibles introduites en utilisant cette balise de modèle avec des données générées par l'utilisateur. Le commentaire d'Amacneil traite de la plupart des préoccupations soulevées dans le ticket.
Je pense que la façon la plus flexible et pratique de le faire est de définir un filtre de modèle pour les variables que vous souhaitez utiliser dans le code JS. Cela vous permet de vous assurer que vos données sont correctement échappées et que vous pouvez les utiliser avec des structures de données complexes, telles que
dict
etlist
. C'est pourquoi j'écris cette réponse malgré qu'il existe une réponse acceptée avec beaucoup de votes positifs.Voici un exemple de filtre de modèle:
Ce modèle filtre convertit la variable en chaîne JSON. Vous pouvez l'utiliser comme ceci:
la source
safe
marque uniquement la valeur comme sûre, sans conversion et échappement appropriés.function myWidget(config) { /* implementation */ }
dans le fichier JS et que vous l'utilisez sur certaines pages en utilisantmyWidget({{ pythonConfig | js }})
. Mais vous ne pouvez pas l'utiliser dans les fichiers JS (comme vous l'avez remarqué), il a donc ses limites.Une solution qui a fonctionné pour moi utilise le champ de saisie caché dans le modèle
Ensuite, obtenir la valeur en javascript de cette façon,
la source
Depuis Django 2.1, une nouvelle balise de modèle intégrée a été introduite spécifiquement pour ce cas d'utilisation:
json_script
.https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
La nouvelle balise sérialisera en toute sécurité les valeurs du modèle et protégera contre XSS.
Extrait de la documentation de Django:
la source
Voici ce que je fais très facilement: j'ai modifié mon fichier base.html pour mon modèle et l'ai mis en bas:
puis quand je veux utiliser une variable dans les fichiers javascript, je crée un dictionnaire DJdata et je l'ajoute au contexte par un json:
context['DJdata'] = json.dumps(DJdata)
J'espère que ça aide!
la source
Pour un dictionnaire, vous devez d'abord encoder en JSON. Vous pouvez utiliser simplejson.dumps () ou si vous souhaitez convertir à partir d'un modèle de données dans App Engine, vous pouvez utiliser encode () à partir de la bibliothèque GQLEncoder.
la source
J'étais confronté à un problème similaire et la réponse suggérée par S.Lott a fonctionné pour moi.
Cependant, je voudrais souligner une limitation de mise en œuvre majeure . Si vous prévoyez de mettre votre code javascript dans un fichier différent et d'inclure ce fichier dans votre modèle. Ça ne marchera pas.
Cela ne fonctionne que lorsque votre modèle principal et le code javascript sont dans le même fichier. L'équipe de Django peut probablement résoudre cette limitation.
la source
J'ai aussi eu du mal avec ça. En surface, il semble que les solutions ci-dessus devraient fonctionner. Cependant, l'architecture django nécessite que chaque fichier html ait ses propres variables rendues (c'est-à-dire,
{{contact}}
est rendu àcontact.html
, tandis que{{posts}}
va à egindex.html
et ainsi de suite). En revanche, les<script>
balises apparaissent après le{%endblock%}
inbase.html
dontcontact.html
etindex.html
héritent. Cela signifie essentiellement que toute solution, y comprisest vouée à l'échec, car la variable et le script ne peuvent pas coexister dans le même fichier.
La solution simple que j'ai finalement trouvée et qui a fonctionné pour moi était de simplement envelopper la variable avec une balise avec id et de la référencer plus tard dans le fichier js, comme ceci:
puis:
et il suffit d' inclure
<script src="static/js/somecode.js"></script>
dansbase.html
comme d' habitude. Bien sûr, il s'agit uniquement d' obtenir le contenu. En ce qui concerne la sécurité, suivez simplement les autres réponses.la source
.textContent
place de.innerHTML
, car sinon les entités qui sont encodées en HTML feront également partie de la variable JS. Mais même alors, il pourrait ne pas être reproduit 1: 1 (je ne suis pas sûr).Pour un objet JavaScript stocké dans un champ Django sous forme de texte, qui doit redevenir un objet JavaScript inséré dynamiquement dans le script sur la page, vous devez utiliser les deux
escapejs
etJSON.parse()
:Django
escapejs
gère correctement les guillemets etJSON.parse()
reconvertit la chaîne en un objet JS.la source
Notez que si vous souhaitez transmettre une variable à un script .js externe, vous devez faire précéder votre balise de script d'une autre balise de script qui déclare une variable globale.
data
est défini dans la vue comme d'habitude dans leget_context_data
la source
J'utilise cette méthode dans Django 2.1 et je travaille pour moi et cette méthode est sécurisée (référence) :
Côté Django:
Côté html:
la source
vous pouvez assembler le script entier où votre variable de tableau est déclarée dans une chaîne, comme suit,
qui générera une chaîne comme suit
après avoir cette chaîne, vous devez l'envoyer au modèle
dans le modèle vous le recevez et l'interprétez de façon littéraire comme du code htm, juste avant le code javascript où vous en avez besoin, par exemple
et en dessous se trouve le reste de votre code, gardez à l'esprit que la variable à utiliser dans l'exemple est data2
de cette façon, vous conserverez le type de données, qui dans ce cas est un arrangement
la source
aaa
ne contiendra que des chiffres, sinon XSS (injection de script) est possible.Il y a deux choses qui ont fonctionné pour moi dans Javascript:
et autres: dans views.py
et en html:
la source