2010-07-27 17 views
21

tengo esto en mi opinión:Django: Analizar JSON en mi plantilla usando 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)) 

¿Cómo iba a "manejar"/convertir datos geográficos en JSON y pasarlo a mi plantilla de manera que pueda " bucle "a través de él como una matriz?

¿Tengo razón en pensar que puedo hacerlo de esta manera? Si no, entonces sugiera una mejor solución.

Gracias!

ACTUALIZACIÓN

var geodata = "[["M. L. Quezon Street<br/>Mandaue City, Philippines", [10.351381999999999, 123.923535]], ["Talamban<br/>Cebu City, Philippines", [10.353527, 123.91352500000001]]]"; 

creo que el JSON no se escapó? ¿Cómo escapo de los caracteres especiales dentro de la cadena json? Sigo recibiendo un error de nueva línea.

Para PHP, me gustaría json_encode() para arreglar esto. Al igual que en esta publicación: Pass a PHP string to a JavaScript variable (and escape newlines) PERO, ¿cómo hago eso en Python/Django?

Respuesta

52

Usted podría utilizar el incorporado en json módulo:

>>> import json 
>>> geodata = [ ("Here", (1003,3004)), ("There", (1.2,1.3)) ] 
>>> json.dumps(geodata) 
'[["Here", [1003, 3004]], ["There", [1.2, 1.3]]]' 

A continuación, puede simplemente incrustar la cadena resultante dentro de un script javascript:

<script type='text/javascript'> 
var geodata = {{ geodata|safe }}; 
</script> 
+0

me da un error después de esta línea: datos geográficos var = "[[" ML Quezon Calle < br/> Mandaue City, Filipinas ", [10,351381999999999, 123.923535]], [" Talamban < br/> Cebu City, Filipinas ", [10.353527, 123.91352500000001]]]; Creo que el JSON no se escapó? ¿Cómo puedo escapar de los caracteres especiales dentro de la cadena json? – wenbert

+0

¿Podría ser que haya agregado a su plantilla 'var geodata =" {{geodata}} ";'? Debería ser sin las comillas. – adamk

+0

No. Lo he intentado sin las comillas. Obtengo un "Símbolo de Syntax no detectado: Token inesperado y" en Google y este error: "var geodata = [[" ML ...;, [10.353527, 123.91352500000001]]]; \ n" en Firefox – wenbert

27

bien, he resuelto mi problema y me gustaría Para responder mi propia pregunta. Pensé que sería mejor para los otros usuarios aquí.

En primer lugar, obtener el archivo aquí: escapejs http://www.JSON.org/json_parse.js

var geodata = json_parse("{{geodata|escapejs}}"); 

acabo de utilizar: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs

EDIT: Gracias a Ignacio Vazquez-Abrams. Fue él quien me ayudó en #python Freenode. Debería haberle acreditado cuando hice esta publicación. No sabía que estaba en Stackoverflow.

+3

Oh, ¿entonces? –

+0

En serio, gracias;) No sabía que estaba en Stackoverflow – wenbert

+0

¿En qué se diferencia esto de usar 'var geodata = eval (" {{geodata | escapejs}} ");'? – simon

9

Si no se preocupan por los navegadores antiguos como Internet Explorer 7, basta con escribir:

var geodata = JSON.parse("{{geodata|escapejs}}"); 

sin ningún tipo de bibliotecas adicionales. Vea http://caniuse.com/#feat=json para las versiones del navegador que soportan JSON.parse().

Creo que la respuesta mejor votada por @adamk tiene un problema potencial con XSS. Si el JSON contiene "</script>", el navegador lo interpreta como el final de la etiqueta <script>. Entonces sería mejor usar el código de @wenbert o el mío.

He intentado hacer comentarios sobre la respuesta directa, pero no tengo la reputación suficiente para hacer eso :)

1

Hay una larga data ticket en django sobre filtro de plantilla, que haría JSON de salida en las plantillas. El problema principal es que es difícil encontrar una solución que pueda usarse en diferentes lugares de html sin introducir XSS. Por ahora se pueden usar los siguientes métodos.

JSON

tienda en html elemento de atributo de datos:

<div data-geodata="{{json_dump_of_geodata}}"></div> 
<script> 
    var geodata = JSON.parse(
     document.querySelectorAll('[data-geodata]')[0].getAttribute('data-geodata') 
); 
</script> 

O usando https://github.com/fusionbox/django-argonauts

<script> 
    var geodata = {{geodata|json}}; 
</script> 

No utilice safe filtro hasta que el 100% seguro de que el JSON no contiene ningún dato de que no se confía fuentes.

1

He encontrado que a menudo quiero tanto la versión del objeto (para el código de la plantilla) como la versión JSON (para el código JavaScript), y resulta un poco molesto pasar ambos por separado a la plantilla cuando uno debería hacerlo bien.

Si desea tomar el enfoque de la etiqueta de la plantilla y no quiere todas las características de django argonauts, entonces puede usar this template tag que siempre me ha servido de gran ayuda. Puede que no sea 100% seguro contra datos no confiables, pero eso nunca ha sido un problema para mis casos de uso.

""" 
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))) 
Cuestiones relacionadas