Подтвердить что ты не робот

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?

4b9b3361

Ответ 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)))