amc*_*cow 16 javascript python django django-templates
我正在研究Django/Python网站.我有一个页面,我想显示一个搜索结果表.结果列表正常传递给模板.
我还想让JavaScript代码可以访问这个对象列表.
我的第一个解决方案是创建另一个返回JSON格式的视图.但每次加载页面都需要调用两次查询.所以我尝试只使用JSON视图下载数据并使用JavaScript打印表.
但这也是不可取的,因为现在表示层被混合到JavaScript代码中.
有没有办法在呈现页面时从Python列表创建JavaScript对象?
Amb*_*ber 21
将Python值转储到JSON的过滤器怎么样?这是一个示例实现:
http://djangosnippets.org/snippets/201/
由于JSON值恰好也是Javascript赋值的有效右侧,因此您可以简单地添加类似...
var results = {{results|jsonify}};
Run Code Online (Sandbox Code Playgroud)
在你的脚本里面.
amc*_*cow 21
解
我创建了自定义模板过滤器,请参阅自定义模板标记和过滤器.
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
Run Code Online (Sandbox Code Playgroud)
对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);
Run Code Online (Sandbox Code Playgroud)
请注意模板标记周围的单引号.
虽然我的下一个问题是 - 它真的很安全吗?
在上述模板标记的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)
Run Code Online (Sandbox Code Playgroud)
Fli*_*imm 11
json_scriptDjango 2.1引入了一个新的模板标签:json_script。它几乎正是您要寻找的,甚至可能更好。它将Python值转换为JSON,包装在<script>标记中。所以这个模板:
{{ value|json_script:"foobar" }}
Run Code Online (Sandbox Code Playgroud)
...将产生以下结果:
<script id="foobar" type="application/json">{"example": "example"}</script>
Run Code Online (Sandbox Code Playgroud)
这不是普通的Javascript <script>标签,它不会运行,而只是JSON。如果要访问Javascript中的内容,可以这样进行:
var value = JSON.parse(document.getElementById('foobar').textContent);
Run Code Online (Sandbox Code Playgroud)
该标签已经过编码,可以正确转义,例如,其中包含的字符串</script>不会破坏任何内容。