Django=を使用してプロジェクト用のWebベースのアプリを作成しています。また、Djangoビューからテンプレート。
この配列は、ページに表示される画像にボックスを描画するためのJavaScript(JQuery)スクリプトによって使用されます。したがって、この配列には、とりわけ、描画されるボックスの座標が含まれます。
これは、必要なデータを取得してJSONとしてシリアル化するために使用されるDjangoビューのコードです:
_def annotate(request, ...):
...
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
tags = serializers.serialize("json", oldAnnotations)
...
return render_to_response('vannotate.html', {'tags': tags, ...})
_
デバッグの方法として、テンプレートのHTML部分で_{{ tags }}
_を使用すると、出力としてこれが得られます(長い行は申し訳ありません)。
_[{"pk": 491, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 220, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 242}}, {"pk": 492, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 218, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 307}}]
_
jSON配列の正しい形式だと思います。
後でテンプレートで、次のようにテンプレートのJavaScript部分でtags
変数を実際に使用しようとします。
_{% if tags %}
var tagbs = {{ tags|safe }};
var tgs = JSON.parse(tagbs);
alert("done");
{% endif %}
_
var tgs = JSON.parse(tagbs);
行を削除すると、アラートボックスが正常にポップアップ表示され、残りのJavaScriptは期待どおりに機能します。ただし、この行をそのままにしておくと、スクリプトが中断されます。
Djangoモデルのすべてのオブジェクトを反復処理し、JavaScriptでフィールドの値を取得できるようにしたいと思います。
ここで何が間違っているのか分かりませんが、誰かがこれを行う正しい方法を指摘できますか?
Django 2.1+および最新のWeb:の更新で編集
これを行う最新の方法は次のとおりです。
1)生データをJSONシリアル化されたデータではなくテンプレートに渡します。つまり:
def annotate(request, ...):
...
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
...
return render_to_response('vannotate.html', {'tags': oldAnnotations, ...})
2)テンプレートで、新しい「json_script」フィルターを使用してJSONデータを含めます。
{{ tags|json_script:"tags-data" }}
その結果、HTMLは次のようになります。
<script id="tags-data" type="application/json">{"foo": "bar"}</script>
このタグには、「</ script>」を含む文字列を特別に処理して、機能するようにします。
3)Javascriptコードで、次のようなタグデータを取得します。
var tags = JSON.parse(document.getElementById('tags-data').textContent);
4)Javascriptコードを外部.jsファイルに移動し、Content-Security-Policyヘッダーを設定して、インラインJavascriptを禁止します。これはセキュリティ上のリスクがあるためです。 json_scriptタグはJavascriptではなくJSONを生成するため、安全であり、Content-Security-Policy設定に関係なく許可されます。
元の答え:
警告:文字列のいずれかがユーザー制御の場合、これは安全ではありません
JSONisJavaScriptのソースコード。つまり配列のJSON表現は、配列を定義するために必要なJavascriptソースコードです。
だから後:
var tagbs = {{ tags|safe }};
tagbs
は、必要なデータを含むJavaScript配列です。 JSON.parse()を呼び出す必要はありません。これは、WebブラウザーがすでにJavaScriptソースコードとして解析しているためです。
だからあなたはできるはずです
var tagbs = {{ tags|safe }};
alert(tagbs[0].fields.ParentVideoFile);
「4」が表示されます。
警告:この古い方法では、「</ script>」を含む文字列は機能せず、ひどく間違ってしまいます。これは、ブラウザが</ script>をスクリプトの終わりとして扱うためです。文字列のいずれかがユーザー入力データである場合、これは悪用可能なセキュリティ上の欠陥です。 詳細についてはコメント14を参照 。代わりに、上記のより新しい方法を使用してください
テンプレートのデータをJSON化したい; JSONはすでにJavascriptです(サブセットです:
{% if tags %}
var tgs = {{ tags }};
{% endif %}
tags
はすでにJSON(つまりJavaScript)データであり、直接挿入できる;エスケープする必要はありません(ここにはHTMLはありません。代わりにJavaScriptです)。
または、この Djangoスニペット を使用して、テンプレートで直接実行することもできます(annotate
メソッドでserializers.serialize
を呼び出す必要はありません)。
var tgs = {{ tags|jsonify }};
Django.utils
からsimplejson
を使用することもできます。お気に入り:
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
dump = simplejson.dumps(oldAnnotations)
return HttpResponse(dump, mimetype='application/json')
JS側からこの中のすべてのデータを解析して到達できます。