Mc-*_*Mc- 37 javascript python django json dom
我正在尝试将一个来自Django的查询集传递给一个带有javascript的模板.
我尝试过不同的方法来解决这个问题:
1.正常方法 - 由于命名法,Javascript会因为尝试解析对象而搞得一团糟[> Object:ID<> Object:ID< ...]
Django View
django_list = list(Some_Object.objects.all())
Run Code Online (Sandbox Code Playgroud)
模板HTML + JS
<script type="text/javascript" >
var js_list = {{django_list}};
</script>
Run Code Online (Sandbox Code Playgroud)
2. JSON方法 - Django无法将对象列表转换为json字符串,而不是JSON可序列化的
Django View
django_list = list(Some_Object.objects.all())
json_list = simplejson.dumps(django_list)
Run Code Online (Sandbox Code Playgroud)
模板HTML + JS
<script type="text/javascript" >
var js_list = {{json_list}};
</script>
Run Code Online (Sandbox Code Playgroud)
所以,我需要一些帮助:)
有人有任何建议/解决方案吗?
谢谢!
agc*_*nti 29
通过回答vashishtha-jogi:
更好的方法是使用DjangoJSONEncoder.它支持Decimal.
Run Code Online (Sandbox Code Playgroud)import json from django.core.serializers.json import DjangoJSONEncoder prices = Price.objects.filter(product=product).values_list('price','valid_from') prices_json = json.dumps(list(prices), cls=DjangoJSONEncoder)非常好用.没有跳过箍将单个字段转换为浮点数.
更新:更改了使用builtin json而不是simplejson的答案.
这个答案在我的谷歌搜索中经常出现,并且有很多观点,这似乎是一个好主意,更新它并保存其他任何人从挖掘SO.假设Django 1.5.
Mc-*_*Mc- 25
好的,我找到了解决方案!
主要是因为没有引用结果.当Javascript试图解析对象时,这不被识别为字符串.
所以,第一步是:
var js_list = {{django_list}};
Run Code Online (Sandbox Code Playgroud)
变成:
var js_list = "{{django_list}}";
Run Code Online (Sandbox Code Playgroud)
在此之后,我意识到Django正在逃避角色,所以我必须像这样替换它们:
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
Run Code Online (Sandbox Code Playgroud)
注意:我试图避免使用以下方法从Django中转义字符:
var js_list = "{{json_list|safe}}";
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为它与引号混淆.
最后,我找到了一种方法来避免在将其发送到Javascript之前转换为JSON的后端逻辑:
var myDjangoList = (("{{django_list |safe}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myDjangoList = myDjangoList.replace(/u'/g, '\'')
myDjangoList = myDjangoList.replace(/'/g, '\"')
myData = JSON.parse( myDjangoList );
Run Code Online (Sandbox Code Playgroud)
我相信这可以改进,我告诉你;)
谢谢你的回答
希望对别人有帮助!
Django的查询集的序列化化JSON.某些字段类型(例如日期,显然),无法序列化.日期对象的解决方法发布在JSON和Python的另一个问题中.
我建议直接在JavaScript中创建字典.鉴于这样的模型:
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
content = models.TextField()
class Author(models.Model):
article = models.ForeignKey("Article", related_name="authors")
first_name=models.CharField(max_length=100)
last_name=models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)
我会在模板中做这样的事情:
<script type="text/javascript">
var articles = [
{% for article in article_list %}
{% if not forloop.first %},{% endif %}
{
title: "{{ article.title }}",
slug: "{{ article.slug }}",
content: "{{ article.content }}",
authors: [
{% for author in article.authors.all %}
{% if not forloop.first %},{% endif %}
{
first_name: "{{ author.first_name }}",
last_name: "{{ author.last_name }}",
}
{% endfor %}
]
}
{% endfor %}
]
</script>
Run Code Online (Sandbox Code Playgroud)
如果您的问题可能有点差,并且不打算在代码中插入代码<script>并且由于某种原因实际上需要 JSON,我只需在视图中执行循环并创建一个dicts 列表,JSON没有问题序列化,和JavaScript没有问题的理解.
编辑:请不要使用这种方法,请参阅@ agconti的答案.
使用escapejs过滤器:https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#escapejs
转储列表的示例:
var foo = [{% for x in y %}'{{ x|escapejs }}',{% endfor %}]
Run Code Online (Sandbox Code Playgroud)
从 Django 2.1 开始,就有了json-script 模板标签。从文档:
json_script
安全地将 Python 对象输出为 JSON,包装在标签中,准备与 JavaScript 一起使用。
参数:标签的 HTML“id”。
例如:
Run Code Online (Sandbox Code Playgroud){{ value|json_script:"hello-data" }}如果 value 是 dictionary
{'hello': 'world'},则输出将为:Run Code Online (Sandbox Code Playgroud)<script id="hello-data" type="application/json"> {"hello": "world"} </script>可以像这样在 JavaScript 中访问结果数据:
Run Code Online (Sandbox Code Playgroud)var value = JSON.parse(document.getElementById('hello-data').textContent);XSS 攻击可以通过转义字符“<”、“>”和“&”来缓解。例如,如果值为
{'hello': 'world</script>&'},则输出为:Run Code Online (Sandbox Code Playgroud)<script id="hello-data" type="application/json"> {"hello": "world\\u003C/script\\u003E\\u0026amp;"} </script>这与禁止页面内脚本执行的严格内容安全策略兼容。它还在被动数据和可执行代码之间保持清晰的分离。
您可以在Django中使用safe和escapejs内置过滤器的组合.
var json_string = unescape({{json_list | safe | escapejs}});
var json_data = JSON.parse(json_string);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51906 次 |
| 最近记录: |