N.b. voir la mise à jour de 2018 au bas de la page
Je vous déconseille de mettre beaucoup de JavaScript dans vos modèles Django - il a tendance à être difficile à écrire et à déboguer, en particulier lorsque votre projet s'étend. Essayez plutôt d'écrire tout votre JavaScript dans un fichier script distinct que votre modèle charge et d'inclure simplement un objet de données JSON dans le modèle. Cela vous permet de faire des choses comme exécuter votre application JavaScript entière à travers quelque chose comme JSLint et vous pouvez le tester avec un fichier HTML statique sans aucune dépendance sur votre application Django. L'utilisation d'une bibliothèque comme simplejson vous permet également d'économiser le temps passé à écrire du code de sérialisation fastidieux.
Si vous ne supposez pas que vous êtes en train de construire une application AJAX, cela peut être fait simplement comme ceci :
Dans la vue :
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, …})
Dans le modèle :
<script type="text/javascript">
data_from_django = {{ my_data }};
widget.init(data_from_django);
</script>
Notez que le type de données importe : si my_data
est un simple nombre ou une chaîne de caractères provenant d'une source contrôlée qui ne contient pas de HTML, comme une date formatée, aucune manipulation spéciale n'est requise. S'il est possible que des données non fiables soient fournies par un utilisateur, vous devrez les assainir en utilisant quelque chose comme la fonction s'échapper o escapejs et assurez-vous que votre JavaScript traite les données en toute sécurité afin d'éviter scripting intersite attaques.
En ce qui concerne les dates, vous pouvez également réfléchir à la manière dont vous les transmettez. J'ai presque toujours trouvé plus facile de les transmettre sous forme de timestamps Unix :
Dans Django :
time_t = time.mktime(my_date.timetuple())
En JavaScript, en supposant que vous ayez fait quelque chose comme time_t = {{ time_t }}
avec les résultats de l'extrait ci-dessus :
my_date = new Date();
my_date.setTime(time_t*1000);
Enfin, tenez compte de l'UTC : les fonctions de date de Python et de Django doivent échanger des données en UTC pour éviter tout décalage gênant par rapport à l'heure locale de l'utilisateur.
EDIT : Notez que le setTime en javascript est en millisecondes alors que la sortie de time.mktime est en secondes. C'est pourquoi nous devons multiplier par 1000.
Mise à jour de 2018 : j'aime toujours JSON pour les valeurs complexes mais dans la décennie qui s'est écoulée. l'API de données HTML5 a atteint support quasi universel des navigateurs et c'est très pratique pour transmettre des valeurs simples (non-list/dict), surtout si vous souhaitez que des règles CSS s'appliquent en fonction de ces valeurs et que vous ne vous souciez pas des versions non prises en charge d'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";
});
Il s'agit d'un moyen efficace d'exposer des données à CSS si vous souhaitez définir l'état initial de la vue dans votre modèle Django et le mettre à jour automatiquement lorsque JavaScript met à jour le fichier data-
attribut. Je l'utilise par exemple pour masquer un widget de progression jusqu'à ce que l'utilisateur sélectionne quelque chose à traiter, pour afficher/masquer de manière conditionnelle les erreurs en fonction des résultats de la recherche ou même pour afficher le nombre d'enregistrements actifs à l'aide d'une feuille de style CSS, par exemple #some-element::after { content: attr(data-active-transfers); }
.
0 votes
Duplicata possible de Variables de modèle Django et Javascript