Шаблон Django - Преобразование списка Python в объект JavaScript - PullRequest
16 голосов
/ 15 января 2011

Я работаю над сайтом Django / Python. У меня есть страница, где я хочу отобразить таблицу результатов поиска. Список результатов передается в шаблон как обычно.

Я также хочу сделать этот список объектов доступным для кода JavaScript.

Моим первым решением было просто создать другое представление, которое вернуло формат JSON . Но каждая загрузка страницы требовала вызова запроса дважды. Тогда я попытался только загрузить данные, используя представление JSON, и распечатать таблицу, используя JavaScript.

Но это также нежелательно, так как теперь слой представления смешан с кодом JavaScript.

Есть ли способ создать объект JavaScript из списка Python при отображении страницы?

Ответы [ 4 ]

21 голосов
/ 15 января 2011

Решение

Я создал собственный шаблонный фильтр, см. пользовательские шаблонные теги и фильтры .

from django.core.serializers import serialize
from django.db.models.query import QuerySet
from django.utils import simplejson
from django.utils.safestring import mark_safe
from django.template import Library

register = Library()

def jsonify(object):
    if isinstance(object, QuerySet):
        return mark_safe(serialize('json', object))
    return mark_safe(simplejson.dumps(object))

register.filter('jsonify', jsonify)
jsonify.is_safe = True   

Важны вызовы mark_safe. В противном случае Джанго избежит этого.

В шаблоне:

//Without template filter (you'll need to serialise in the view)
var data = jQuery.parseJSON('{{ json_data|safe }}');
alert(data.length);

//Using the template filter    
var data2 = jQuery.parseJSON('{{ record_list|jsonify }}');
alert(data2.length);

Обратите внимание на одинарные кавычки вокруг тега шаблона.

Хотя мой следующий вопрос будет - ДЕЙСТВИТЕЛЬНО ли это безопасно?

Обновление

Обновленная версия, работающая в django 1.8 вышеупомянутого тега шаблона, которая также обрабатывает передаваемый список плоских значений, т.е. values_list ('myfield', flat = True):

from django.core.serializers import serialize
from django.db.models.query import QuerySet, ValuesListQuerySet
from django.template import Library

import json

register = Library()

@register.filter( is_safe=True )
def jsonify(object):

    if isinstance(object, ValuesListQuerySet):
        return json.dumps(list(object))
    if isinstance(object, QuerySet):
        return serialize('json', object)
    return json.dumps(object)
21 голосов
/ 15 января 2011

Как насчет фильтра, который выводит значение Python в JSON? Вот пример реализации:

http://djangosnippets.org/snippets/201/

Поскольку значение JSON также является допустимой правой частью для назначения Javascript, вы можете просто поместить что-то вроде ...

var results = {{results|jsonify}};

внутри вашего скрипта.

7 голосов
/ 04 октября 2018

Новое в Django 2.1: json_script

В Django 2.1 появился новый тег шаблона: json_script.Это почти то, что вы ищете, может быть, даже лучше.Он преобразует значение Python в JSON, заключенное в тег <script>.Итак, этот шаблон:

{{ value|json_script:"foobar" }}

... будет производить это:

<script id="foobar" type="application/json">{"example": "example"}</script>

Это не обычный тег Javascript <script>, он не запускается, это просто JSON.Если вы хотите получить доступ к содержимому вашего Javascript, вы можете сделать это следующим образом:

var value = JSON.parse(document.getElementById('foobar').textContent);

Этот тег был закодирован так, что он правильно экранирован, строка с </script> не будетсломать что-нибудь, например.

0 голосов
/ 23 июля 2015

Смотри этот ответ тоже.

Но это не высокоскоростной способ. Вы должны:

a) Создать JSON-файлы, поместить их на диск или S3. В случае, если JSON статический

б) Если JSON динамический. Создайте JSON по отдельному URL (например, API) в вашем приложении.

И, загрузить в JS напрямую в любом случае. Например:

$.ajax('/get_json_file.json')

P.S .: Извините за мой английский.

...