it-swarm.com.ru

Шаблонные переменные Django и Javascript

Когда я отображаю страницу, используя средство визуализации шаблонов Django, я могу передать переменную словаря, содержащую различные значения, чтобы манипулировать ими на странице с помощью {{ myVar }}.

Есть ли способ получить доступ к той же переменной в Javascript (возможно, используя DOM, я не знаю, как Django делает переменные доступными)? Я хочу иметь возможность искать детали с помощью поиска AJAX на основе значений, содержащихся в переданных переменных.

166
AlMcLean

Код {{variable}} подставляется непосредственно в HTML. Сделать вид источника; это не «переменная» или что-то подобное. Это просто визуализированный текст.

Сказав это, вы можете поместить такую ​​замену в свой JavaScript.

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

Это дает вам «динамический» JavaScript.

238
S.Lott

CAUTION Проверьте тикет # 17419 для обсуждения добавления аналогичного тега в ядро ​​Django и возможных уязвимостей XSS, появившихся при использовании этого тега шаблона с данными, сгенерированными пользователем. Комментарий от 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>
47
Yaroslav Admin

Решение, которое сработало для меня, заключается в использовании скрытого поля ввода в шаблоне

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

Затем получить значение в JavaScript таким образом,

var myVar = document.getElementById("myVar").value;
39
bosco-

Когда переменная возвращается Django, она превращает все кавычки в &quot;. Использование {{someDjangoVariable|safe}} вызывает ошибку Javascript. 

Чтобы исправить это, используйте Javascript .replace:

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

Для словаря лучше всего сначала кодировать в JSON. Вы можете использовать simplejson.dumps () или если вы хотите преобразовать модель данных в App Engine, вы можете использовать encode () из библиотеки GQLEncoder. 

8
jamtoday

Вот что я делаю очень легко: Я изменил свой файл base.html для своего шаблона и поместил его внизу:

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

затем, когда я хочу использовать переменную в файлах javascript, я создаю словарь DJdata и добавляю его в контекст с помощью json: context['DJdata'] = json.dumps(DJdata)

Надеюсь, поможет!

6
Alexis Parakian

Я столкнулся с вопросом о подобии, и ответ, предложенный С. Лоттом, работал на меня.

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

Однако я хотел бы отметить основные ограничения реализации здесь . Если вы планируете поместить свой код JavaScript в другой файл и включить этот файл в свой шаблон. Это не сработает.

Это работает только тогда, когда вы используете основной шаблон и код JavaScript в одном и том же файле. Возможно, команда Django может устранить это ограничение.

3
Conquistador

Я тоже боролся с этим. На первый взгляд кажется, что вышеуказанные решения должны работать. Однако архитектура Django требует, чтобы каждый html-файл имел свои собственные отображаемые переменные (то есть {{contact}} отображается в contact.html, тогда как {{posts}} переходит, например, к index.html и так далее). С другой стороны, теги <script> появляются после {%endblock%} в base.html, от которого наследуются contact.html и index.html. Это в основном означает, что любое решение, включая 

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

обязательно потерпит неудачу, потому что переменная и скрипт не могут сосуществовать в одном и том же файле. 

Простое решение, которое я в конце концов придумал и сработало для меня, заключалось в том, чтобы просто обернуть переменную тегом с идентификатором, а затем обратиться к нему в файле 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 как обычно . Конечно, это касается только получения содержимого. Что касается безопасности, просто следуйте другим ответам. 

2
Shoval Sadde

Начиная с Django 2.1, новый встроенный тег шаблона был введен специально для этого случая использования: json_script.

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

Новый тег безопасно сериализует значения шаблона и защищает от XSS.

1
Jon Sakas

Обратите внимание, что если вы хотите передать переменную во внешний скрипт .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
0
Daniel Kislyuk

Для объекта JavaScript, хранящегося в поле Django в виде текста, который должен снова стать объектом JavaScript, динамически вставляемым в сценарий на странице, необходимо использовать escapejs и JSON.parse():

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

escapejs в Django правильно обрабатывает цитирование, а JSON.parse() преобразует строку обратно в объект JS.

0
shacker