Переменные шаблона Django и Javascript
Когда я создаю страницу с помощью средства визуализации Django, я могу передать переменную словаря, содержащую различные значения, чтобы манипулировать ими на странице с помощью {{ myVar }}
.
Есть ли способ получить доступ к одной и той же переменной в Javascript (возможно, используя DOM, я не знаю, как Django делает переменные доступными)? Я хочу иметь возможность искать информацию, используя поиск AJAX, основанный на значениях, содержащихся в переданных переменных.
Ответы
Ответ 1
{{variable}}
подставляется непосредственно в HTML. Использовать источник просмотра; это не "переменная" или что-то в этом роде. Он просто визуализировал текст.
Сказав это, вы можете поместить такую замену в свой JavaScript.
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
Это дает вам "динамический" javascript.
Ответ 2
ПРЕДОСТЕРЕЖЕНИЕ Проверить флажок # 17419 для обсуждения добавления подобного тега в ядро Django и возможных уязвимостей XSS, введенных с помощью этот тег шаблона с пользовательскими данными. Comment от 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>
Ответ 3
Решение, которое сработало для меня, использует скрытое поле ввода в шаблоне
<input type="hidden" id="myVar" name="variable" value="{{ variable }}">
Затем, получив значение в javascript таким образом,
var myVar = document.getElementById("myVar").value;
Ответ 4
Начиная с Django 2.1, новый встроенный тег шаблона был введен специально для этого варианта использования: json_script
.
https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#json-script.
Новый тег безопасно сериализует значения шаблона и защищает от XSS.
Ответ 5
Для словаря, вы лучше всего кодируете JSON. Вы можете использовать simplejson.dumps() или если вы хотите преобразовать из модели данных в App Engine, вы можете использовать encode() из библиотеки GQLEncoder.
Ответ 6
Когда переменная возвращается Django, она превращает все кавычки в "
. Использование {{someDjangoVariable|safe}}
вызывает ошибку Javascript.
Чтобы исправить это, используйте Javascript .replace
:
<script type="text/javascript">
var json = "{{someDjangoVariable}}".replace(/"/g,"\"")
</script>
Ответ 7
Вот что я делаю очень легко:
Я изменил файл base.html для своего шаблона и поместил его внизу:
{% if DJdata %}
<script type="text/javascript">
(function () {window.DJdata = {{DJdata|safe}};})();
</script>
{% endif %}
то когда я хочу использовать переменную в файлах javascript, я создаю словарь DJdata и добавляю его в контекст json: context['DJdata'] = json.dumps(DJdata)
Надеюсь, что это поможет!
Ответ 8
Я столкнулся с проблемой simillar, и ответ, предложенный S.Lott, работал на меня.
<script type="text/javascript">
var a = "{{someDjangoVariable}}"
</script>
Однако я хотел бы указать здесь значительное ограничение реализации.
Если вы планируете разместить свой javascript-код в другом файле и включить этот файл в свой шаблон. Это не сработает.
Это работает только тогда, когда основной шаблон и код javascript находятся в одном файле.
Возможно, команда django может решить эту проблему.
Ответ 9
Я тоже боролся с этим. На первый взгляд кажется, что вышеуказанные решения должны работать. Однако архитектура django требует, чтобы у каждого html файла были свои отображаемые переменные (то есть {{contact}}
отображается в contact.html
, а {{posts}}
- например, index.html
и т.д.). С другой стороны, теги <script>
появляются после {%endblock%}
в base.html
от которого наследуются contact.html
и index.html
. Это в основном означает, что любое решение, включая
<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
как обычно. Конечно, это только получение контента. Что касается безопасности, просто следуйте другим ответам.
Ответ 10
Для объекта JavaScript, хранящегося в поле Django в качестве текста, который должен снова стать объектом JavaScript, динамически вставленным на страницу script, вам необходимо использовать как escapejs
, так и JSON.parse()
:
var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}");
Django escapejs
корректно обрабатывает цитирование, а JSON.parse()
преобразует строку обратно в объект JS.
Ответ 11
Обратите внимание, что если вы хотите передать переменную во внешний скрипт .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
Ответ 12
Вы можете собрать весь сценарий, где ваша переменная массива объявлена в строке, следующим образом:
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>
таким образом вы сохраните тип данных, который в данном случае является договоренностью