我正在研究Django / Python网站。我有一个页面,我想显示一个搜索结果表。结果列表将照常传递给模板。
我还想让JavaScript代码可以访问这个对象列表。
我的第一个解决方案是创建另一个返回JSON格式的视图。但每次加载页面都需要调用两次查询。因此,我尝试仅使用JSON视图下载数据并使用JavaScript打印表。
但这也是不可取的,因为现在表示层被混合到JavaScript代码中。
有没有办法在呈现页面时从Python列表创建JavaScript对象?
答案 0 :(得分:21)
将Python值转储到JSON的过滤器怎么样?这是一个示例实现:
http://djangosnippets.org/snippets/201/
由于JSON值恰好也是Javascript赋值的有效右侧,因此您可以简单地添加类似...
var results = {{results|jsonify}};
在你的剧本里面。
答案 1 :(得分:21)
<强>解决方案强>
我创建了自定义模板过滤器,请参阅 custom template tags and filters 。
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的调用很重要。否则Django会逃脱它。
在模板中:
//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)
答案 2 :(得分:6)
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>
的字符串不会破坏任何内容。
答案 3 :(得分:-1)
也看this answer。
但它不是高负荷的方式。你必须:
a)创建JSON文件,放置到磁盘或S3。如果是JSON静态
b)如果JSON是动态的。在您的应用中单独生成JSON(如API)。
并且,无论如何都直接由JS加载。例如:
$.ajax('/get_json_file.json')
P.S。:对不起我的英语。