回答:
{{variable}}
HTMLに直接代入されます。ソースを表示します。「変数」やそのようなものではありません。レンダリングされたテキストです。
そうは言っても、この種の置換をJavaScriptに組み込むことができます。
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
これにより、「動的」なJavaScriptが提供されます。
escapejs
フィルタが存在している:escapejs('<>') -> u'\\u003C\\u003E'
注意同様のタグをDjangoコアに追加する方法、およびこのテンプレートタグをユーザー生成データで使用することにより発生する可能性のあるXSS脆弱性については、チケット#17419を確認してください。amacneilからのコメントは、チケットで提起された懸念のほとんどについて説明しています。
これを行うための最も柔軟で便利な方法は、JSコードで使用する変数のテンプレートフィルターを定義することだと思います。これにより、データが適切にエスケープされdict
、やなどの複雑なデータ構造で使用できるようになりlist
ます。多くの賛成票で承認された回答があるにもかかわらず、私がこの回答を書いたのはそのためです。
テンプレートフィルターの例を次に示します。
// 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))
このテンプレートは、変数をJSON文字列に変換します。次のように使用できます。
// myapp/templates/example.html
{% load js %}
<script type="text/javascript">
var someVar = {{ some_var | js }};
</script>
safe
適切な変換とエスケープを行わずに、値を安全とマークするだけです。
function myWidget(config) { /* implementation */ }
、JSファイルで宣言し、を使用して一部のページで使用するとしますmyWidget({{ pythonConfig | js }})
。ただし、JSファイルでは(気付かれたように)使用できないため、制限があります。
私のために働いた解決策は、テンプレートの非表示の入力フィールドを使用することです
<input type="hidden" id="myVar" name="variable" value="{{ variable }}">
次に、JavaScriptでこの方法で値を取得します。
var myVar = document.getElementById("myVar").value;
Django 2.1以降、この使用例のために新しい組み込みテンプレートタグが導入されました:json_script
。
https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
新しいタグはテンプレート値を安全にシリアル化し、XSSから保護します。
Djangoドキュメントの抜粋:
PythonオブジェクトをJSONとして安全に出力し、タグでラップして、JavaScriptですぐに使用できます。
これが私が非常に簡単にやっていることです:私は自分のテンプレートのbase.htmlファイルを変更し、それを一番下に置きました:
{% if DJdata %}
<script type="text/javascript">
(function () {window.DJdata = {{DJdata|safe}};})();
</script>
{% endif %}
次に、JavaScriptファイルで変数を使用する場合は、DJdata辞書を作成し、jsonを使用してコンテキストに追加します。 context['DJdata'] = json.dumps(DJdata)
それが役に立てば幸い!
辞書の場合、最初にJSONにエンコードするのが最善です。simplejson.dumps()を使用できます。AppEngineのデータモデルから変換する場合は、GQLEncoderライブラリのencode()を使用できます。
私は類似の問題に直面しており、S.Lottが提案した回答がうまくいきました。
<script type="text/javascript">
var a = "{{someDjangoVariable}}"
</script>
ただし、ここで主要な実装上の制限を指摘したいと思います。JavaScriptコードを別のファイルに入れて、そのファイルをテンプレートに含めることを計画している場合。これは機能しません。
これは、メインテンプレートとJavaScriptコードが同じファイルにある場合にのみ機能します。おそらくdjangoチームがこの制限に対処できます。
私もこれに苦労しています。表面的には、上記のソリューションが機能するはずです。ただし、djangoアーキテクチャでは、各htmlファイルに独自のレンダリングされた変数(つまり、eg などに移動するときにに{{contact}}
レンダリングされる)が必要です。一方、contact.html
{{posts}}
index.html
<script>
タグは{%endblock%}
、base.html
from from contact.html
およびindex.html
inheritの後に表示されます。これは基本的に、
<script type="text/javascript">
var myVar = "{{ myVar }}"
</script>
変数とスクリプトが同じファイルに共存できないため、失敗するようにバインドされています。
私が最終的に思いついて私のために働いた簡単な解決策は、変数をidのタグで単にラップし、後でjsファイルでそれを参照することでした:
// index.html
<div id="myvar">{{ myVar }}</div>
その後:
// somecode.js
var someVar = document.getElementById("myvar").innerHTML;
そしてちょうど含ん<script src="static/js/somecode.js"></script>
でbase.html
いつものように。もちろん、これはコンテンツを取得するためだけのものです。セキュリティに関しては、他の答えに従ってください。
.textContent
代わりに使用する必要があります。.innerHTML
そうしないと、HTMLエンコードされたエンティティもJS変数の一部になるためです。しかし、それでも1対1で再現されない可能性があります(わかりません)。
変数を外部の.jsスクリプトに渡す場合は、スクリプトタグの前に、グローバル変数を宣言する別のスクリプトタグを付ける必要があることに注意してください。
<script type="text/javascript">
var myVar = "{{ myVar }}"
</script>
<script type="text/javascript" src="{% static "scripts/my_script.js" %}"></script>
data
通常どおりビューで定義されます get_context_data
def get_context_data(self, *args, **kwargs):
context['myVar'] = True
return context
次のように、配列変数が文字列で宣言されているスクリプト全体をアセンブルできます。
views.py
aaa = [41, 56, 25, 48, 72, 34, 12]
prueba = "<script>var data2 =["
for a in aaa:
aa = str(a)
prueba = prueba + "'" + aa + "',"
prueba = prueba + "];</script>"
次のように文字列を生成します
prueba = "<script>var data2 =['41','56','25','48','72','34','12'];</script>"
この文字列を取得したら、テンプレートに送信する必要があります
views.py
return render(request, 'example.html', {"prueba": prueba})
テンプレートでは、それを受け取り、それを文学的な方法でhtmコードとして解釈します。たとえば、必要なJavaScriptコードの直前です。
テンプレート
{{ prueba|safe }}
以下は残りのコードです。この例で使用する変数はdata2であることに注意してください
<script>
console.log(data2);
</script>
このようにして、データのタイプ(この場合は配置)を保持します
aaa
は数値のみが含まれることが確実な場合にのみ使用してください。そうでない場合は、XSS(スクリプト挿入)が可能です。