2013-03-23 16 views
21

Używam Django do tworzenia aplikacji internetowej dla projektu i mam problemy z zwracaniem tablicy z widoku Django do szablonu.Powracanie tablicy JSON z widoku Django do szablonu

Tablica będzie używana przez skrypt JavaScript (JQuery) do rysowania pól na obrazie widocznym na stronie. Dlatego ta tablica będzie zawierać, między innymi, współrzędne dla pól do narysowania.

Jest to kod w widoku Django używane, aby uzyskać wymagane dane i szeregować je jako JSON:

def annotate(request, ...): 
    ... 
    oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label) 
    tags = serializers.serialize("json", oldAnnotations) 
    ... 
    return render_to_response('vannotate.html', {'tags': tags, ...}) 

Jako sposób debugowania, używając {{ tags }} w części HTML szablonu daje to jako wyjście (przepraszam za długą linię):

[{"pk": 491, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 220, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 242}}, {"pk": 492, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 218, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 307}}] 

który zakładam, jest poprawnym formatem dla tablicy JSON.

Później w szablonie, próbuję faktycznie użyć zmiennej tags w części JavaScript szablonu, co następuje:

{% if tags %} 
    var tagbs = {{ tags|safe }}; 
    var tgs = JSON.parse(tagbs); 
    alert("done"); 
{% endif %} 

Jeśli usunąć linię var tgs = JSON.parse(tagbs);, wtedy alert box wyskakuje porządku , a reszta kodu JavaScript działa zgodnie z oczekiwaniami. Pozostawienie tego wiersza powoduje jednak przerwanie skryptu.

Chcę móc wykonywać iteracje po wszystkich obiektach w modelu Django i uzyskiwać wartości pól w JavaScript.

Nie jestem pewien, co robię źle tutaj, czy ktoś może wskazać właściwą drogę, aby to zrobić?

+1

Nie przesyłasz danych do JavaScript, po stronie serwera wstrzykujesz do skryptu, a zatem kod jest interpretowany jako JavaScript na kliencie. Jeśli spojrzysz na źródło, zobaczysz, że jest to normalna literatura. W tym kontekście nie jest to JSON, więc nie możesz go przetworzyć. –

Odpowiedz

34

JSON jest kodu źródłowego JavaScript. To znaczy. reprezentacja JSON tablicy jest kodem źródłowym JavaScript potrzebnym do zdefiniowania tablicy.

Więc po:

var tagbs = {{ tags|safe }}; 

tagbs jest tablicą JavaScript zawierający dane, które chcesz. Nie ma potrzeby wywoływania JSON.parse(), ponieważ przeglądarka internetowa przetwarza ją już jako kod źródłowy JavaScript.

więc powinieneś być w stanie zrobić

var tagbs = {{ tags|safe }}; 
alert(tagbs[0].fields.ParentVideoFile); 

i że powinien pokazać "4".

+2

Mężczyzna, kocham StackOverflow. Ta drobna poprawka rozwiązała wszystko! Jestem na to nowy, myślałem, że JSON.parse przetworzył zmienną JSON na tablicę, a nie odwrotnie. Wielkie dzięki! – DefPlayr

+0

Nie powinieneś używać '| safe' tutaj; to jest potrzebne tylko do sanityzacji HTML. JSON już zrobił to bezpieczne JavaScript, każda treść HTML powinna * nie * być unikana. –

+2

Hmmm, próbowałem usunąć '| safe', ale to nie działa wtedy. – DefPlayr

4

Chcesz JSON-ify danych w szablonie; JSON jest już Javascript naprawdę (jest to podzbiór:

{% if tags %} 
    var tgs = {{ tags }}; 
{% endif %} 

Zauważ, że tags jest już JSON (zatem JavaScript) dane i może być włożona bezpośrednio nie ma potrzeby, aby uciec (nie ma Kopiuj tutaj, to JavaScript zamiast .)

Albo można użyć tego Django snippet i zrobić to prosto w szablonie (nie trzeba zadzwonić serializers.serialize w metodzie annotate):

var tgs = {{ tags|jsonify }}; 
+0

Czy mam umieścić definicję filtru 'jsonify' w pliku' views'? Próbowałem postępować zgodnie z instrukcjami na łączu, ale Django powiedział mi, że filtr 'jsonify' jest nieprawidłowy. – DefPlayr

+0

@ user2203255: umieść go w nowym pod-pakiecie 'templatetags' (katalogu z plikiem' __init __. Py') obok 'models.py' i' views.py', zobacz https: //docs.djangoproject. com/en/dev/howto/custom-template-tags/ –

+0

Świetne, że działa też! I upraszcza to później. Ale jedno. Musiałem dodać dodatkową potokę do 'safe' (tj.' {{Tags | jsonify | safe}} '), aby ją uruchomić. Być może ma to związek z samym obiektem. – DefPlayr

2

Można również użyć simplejson z django.utils. Podobnie jak:

oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label) 
dump = simplejson.dumps(oldAnnotations) 

return HttpResponse(dump, mimetype='application/json') 

Możesz analizować i uzyskiwać dostęp do wszystkich danych w tym od strony JS.

+4

To jest przestarzałe w [Django 1.5] (https: //docs.djangoproject .com/pl/dev/releases/1.5/# system-wersja-of-simplejson-no-longer-used) – Ngenator