2010-07-27 13 views
21

Tôi có điều này theo quan điểm của tôi:Django: Phân tích JSON trong mẫu của tôi sử dụng 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)) 

Làm thế nào tôi "xử lý"/chuyển đổi geodata thành JSON và vượt qua nó để mẫu của tôi để tôi có thể " vòng lặp "thông qua nó như một mảng?

Tôi có quyền nghĩ rằng mình có thể làm theo cách này không? Nếu không, thì hãy đề xuất một giải pháp tốt hơn.

Cảm ơn!

CẬP NHẬT

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

Tôi nghĩ rằng JSON không thoát? Làm cách nào để thoát khỏi các ký tự đặc biệt bên trong chuỗi json? Tôi tiếp tục gặp phải lỗi mới.

Đối với PHP, tôi sẽ json_encode() để sửa lỗi này. Như trong bài viết này: Pass a PHP string to a JavaScript variable (and escape newlines) NHƯNG làm cách nào để làm điều đó trong Python/Django?

Trả lời

52

Bạn có thể sử dụng được xây dựng trong json mô-đun:

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

Sau đó, bạn có thể chỉ cần nhúng chuỗi kết quả trong một kịch bản javascript:

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

tôi nhận được một lỗi sau khi dòng này: var geodata = "[[" ML Quezon đường < br/> Mandaue City, Philippines ", [10,351381999999999, 123,923535]], [" Talamban < br/> Thành phố Cebu, Philippines ", [10.353527, 123.91352500000001]]] "; Tôi nghĩ rằng JSON không được thoát? Làm cách nào để thoát khỏi các ký tự đặc biệt bên trong chuỗi json? – wenbert

+0

Có thể bạn đã thêm vào mẫu của mình 'var geodata =" {{geodata}} ";'? Nó sẽ không có dấu ngoặc kép. – adamk

+0

Không. Tôi đã thử mà không có dấu ngoặc kép. Tôi nhận được thông báo lỗi "Uncaught SyntaxError: Unexpected token &" trong Google và lỗi này: "var geodata = [[" ML .. ;, [10.353527, 123.91352500000001]]]; \ n" trong Firefox – wenbert

27

Được rồi, tôi giải quyết vấn đề của tôi và muốn để trả lời câu hỏi của riêng tôi. Tôi nghĩ rằng nó sẽ tốt hơn cho những người dùng khác ở đây.

Đầu tiên, lấy file ở đây: escapejs http://www.JSON.org/json_parse.js

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

tôi chỉ sử dụng: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs

EDIT: Nhờ Ignacio Vazquez-Abrams. Chính anh ta đã giúp tôi trong #python Freenode. Có lẽ đã ghi nhận anh ấy khi tôi thực hiện bài đăng này. Tôi không biết anh ta đang ở trong Stackoverflow.

+3

Oh bạn đã làm vậy rồi. –

+0

Nghiêm túc cảm ơn;) Tôi không biết bạn đang ở trong Stackoverflow – wenbert

+0

cách này khác với việc sử dụng 'var geodata = eval (" {{geodata | escapejs}} ");'? – simon

9

Nếu bạn không quan tâm về các trình duyệt cũ như IE7, bạn chỉ có thể viết:

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

mà không cần bất kỳ thư viện thêm. Xem http://caniuse.com/#feat=json cho các phiên bản trình duyệt hỗ trợ JSON.parse().

Tôi tin rằng câu trả lời được bình chọn hàng đầu bởi @adamk có vấn đề XSS tiềm ẩn. Nếu JSON chứa "</script>", trình duyệt sẽ giải thích nó là kết thúc của <script> thẻ. Vì vậy, nó sẽ là tốt hơn để sử dụng mã của @wenbert hoặc của tôi.

Tôi cố gắng để nhận xét về câu trả lời trực tiếp, nhưng tôi không có đủ uy tín để làm điều đó :)

1

Có một từ lâu ticket trong django về mẫu bộ lọc mà sẽ ra json theo mẫu. Vấn đề chính là khó có thể đưa ra một giải pháp có thể được sử dụng ở những nơi khác nhau của html mà không cần giới thiệu XSS. Hiện tại, các phương pháp sau có thể được sử dụng.

cửa hàng json trong html thuộc tính dữ liệu phần tử:

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

Hoặc sử dụng https://github.com/fusionbox/django-argonauts

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

Không sử dụng safe lọc cho đến khi bạn chắc chắn 100% rằng json không chứa bất kỳ dữ liệu từ không tin cậy nguồn.

1

Tôi đã tìm thấy rằng tôi thường muốn cả phiên bản đối tượng (đối với mã mẫu) và phiên bản JSON (đối với mã JavaScript) và thấy khó chịu khi chuyển cả hai vào mẫu riêng lẻ khi người dùng làm tốt.

Nếu bạn muốn thực hiện phương pháp tiếp cận thẻ mẫu và không muốn tất cả các chuông và còi của django argonauts thì bạn có thể sử dụng this template tag vốn luôn thực hiện thủ thuật cho tôi. Nó có thể không an toàn 100% so với dữ liệu không đáng tin cậy nhưng đó không bao giờ là vấn đề đối với các trường hợp sử dụng của tôi.

""" 
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))) 
Các vấn đề liên quan