Django: проанализируйте JSON в моем шаблоне, используя Javascript
У меня это на мой взгляд:
string_location = myaddress2
geodata = []
for place, (lat, lng) in g.geocode(string_location,exactly_one=False):
geodata.append((place, (lat, lng)))
geodata_results = len(geodata)
data = {"geodata": geodata, "geodata_results":geodata_results }
return render_to_response("business/business_view.html",
data, context_instance=RequestContext(request))
Как бы я "обрабатывал" /конвертировал геоданные в JSON и передавал его моему шаблону, чтобы я мог "перебирать" его через массив?
Я прав, чтобы думать, что я могу сделать это таким образом? Если нет, то, пожалуйста, предложите лучшее решение.
Спасибо!
UPDATE
var geodata = "[["M. L. Quezon Street<br/>Mandaue City, Philippines", [10.351381999999999, 123.923535]], ["Talamban<br/>Cebu City, Philippines", [10.353527, 123.91352500000001]]]";
Я думаю, что JSON не сбежал? Как избежать специальных символов внутри строки json?
Я продолжаю получать ошибку новой строки.
Для PHP я хотел бы json_encode() исправить это. Как в этом сообщении: Передайте строку PHP в переменную JavaScript (и выйдите из новой строки), но как это сделать в Python/Django?
Ответы
Ответ 1
Вы можете использовать встроенный модуль json
:
>>> import json
>>> geodata = [ ( "Here", (1003,3004) ), ("There", (1.2,1.3)) ]
>>> json.dumps(geodata)
'[["Here", [1003, 3004]], ["There", [1.2, 1.3]]]'
Затем вы можете просто вставить результирующую строку в javascript script:
<script type='text/javascript'>
var geodata = {{ geodata|safe }};
</script>
Ответ 2
Хорошо, я решил свою проблему и хотел бы ответить на мой собственный вопрос. Я решил, что для других пользователей здесь будет лучше.
Сначала найдите файл здесь: http://www.JSON.org/json_parse.js
var geodata = json_parse("{{geodata|escapejs}}");
Я просто использовал escapejs: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs
EDIT: Спасибо Игнасио Васкес-Абрамсу. Именно он помог мне в #python Freenode. Должен был зачислить его, когда я сделал это сообщение. Я не знал, что он был в Stackoverflow.
Ответ 3
Если вам не нравятся старые браузеры, такие как IE7, вы можете просто написать:
var geodata = JSON.parse("{{geodata|escapejs}}");
без дополнительных библиотек. См. http://caniuse.com/#feat=json для версий браузера, поддерживающих JSON.parse().
Я полагаю, что голосовой ответ от @adamk имеет потенциальную проблему XSS. Если JSON содержит "</script>"
, браузер интерпретирует его как конец тега <script>
. Поэтому было бы лучше использовать код @wenbert или мой.
Я попытался прокомментировать ответ напрямую, но у меня недостаточно репутации, чтобы сделать это:)
Ответ 4
Существует долгое время ticket в django относительно фильтра шаблонов, который выводит json в шаблонах. Основная проблема заключается в том, что трудно найти решение, которое можно использовать в разных местах html без внедрения XSS. В настоящее время можно использовать следующие методы.
Сохранить json в атрибуте данных элемента html:
<div data-geodata="{{json_dump_of_geodata}}"></div>
<script>
var geodata = JSON.parse(
document.querySelectorAll('[data-geodata]')[0].getAttribute('data-geodata')
);
</script>
Или используя https://github.com/fusionbox/django-argonauts
<script>
var geodata = {{geodata|json}};
</script>
Не используйте фильтр safe
, пока вы не убедитесь, что json не содержит данных из ненадежных источников.
Ответ 5
Я обнаружил, что мне часто требуются как версия объекта (для кода шаблона), так и версия JSON (для кода JavaScript), и находят, что это немного раздражает, чтобы передавать как по отдельности шаблону, когда нужно делать все правильно.
Если вы хотите использовать подход тэга шаблона и не хотите, чтобы все звонки django argonauts, вы можете использовать этот тег шаблона, который всегда делал трюк для меня. Он не может быть на 100% безопасен от ненадежных данных, но это никогда не было проблемой для моих случаев использования.
"""
Usage:
{% import json_tags %}
var = myJsObject = {{ template_var|to_json }};
Features:
- Built in support for dates, datetimes, lazy translations.
- Safe escaping of script tags.
- Support for including QuryDict objects.
- Support for custom serialization methods on objects via defining a `to_json()` method.
"""
import datetime
import json
from decimal import Decimal
from django import template
from django.http import QueryDict
from django.utils.encoding import force_str
from django.utils.functional import Promise
from django.utils.safestring import mark_safe
register = template.Library()
ISO_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
def json_handler(obj):
if callable(getattr(obj, 'to_json', None)):
return obj.to_json()
elif isinstance(obj, datetime.datetime):
return obj.strftime(ISO_DATETIME_FORMAT)
elif isinstance(obj, datetime.date):
return obj.isoformat()
elif isinstance(obj, datetime.time):
return obj.strftime('%H:%M:%S')
elif isinstance(obj, Decimal):
return float(obj) # warning, potential loss of precision
elif isinstance(obj, Promise):
return force_str(obj) # to support ugettext_lazy
else:
return json.JSONEncoder().default(obj)
@register.filter
def to_json(obj):
def escape_script_tags(unsafe_str):
# seriously: http://stackoverflow.com/a/1068548/8207
return unsafe_str.replace('</script>', '<" + "/script>')
# json.dumps does not properly convert QueryDict array parameter to json
if isinstance(obj, QueryDict):
obj = dict(obj)
return mark_safe(escape_script_tags(json.dumps(obj, default=json_handler)))