将对象从Django传递到Javascript DOM
我试图用javascript将Django的查询集传递给模板 我尝试了不同的方法来解决这个问题: 1。正常方法-由于命名法[>-object:ID<,>-object:ID<,…]的原因,Javascript在尝试解析对象时遇到了麻烦。 Django视图将对象从Django传递到Javascript DOM,javascript,python,django,json,dom,Javascript,Python,Django,Json,Dom,我试图用javascript将Django的查询集传递给模板 我尝试了不同的方法来解决这个问题: 1。正常方法-由于命名法[>-object:ID<,>-object:ID<,…]的原因,Javascript在尝试解析对象时遇到了麻烦。 Django视图 django_list = list(Some_Object.objects.all()) django_list = list(Some_Object.objects.all()) json_list = simplejso
django_list = list(Some_Object.objects.all())
django_list = list(Some_Object.objects.all())
json_list = simplejson.dumps(django_list)
模板HTML+JS
<script type="text/javascript" >
var js_list = {{django_list}};
</script>
<script type="text/javascript" >
var js_list = {{json_list}};
</script>
模板HTML+JS
<script type="text/javascript" >
var js_list = {{django_list}};
</script>
<script type="text/javascript" >
var js_list = {{json_list}};
</script>
var js_list={{json_list}};
所以,我需要一些帮助:)
有人有什么建议/解决方案吗
谢谢 Django查询集。某些字段类型(例如date,显然)无法在is处序列化。日期对象的解决方法已发布到
我建议直接在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)
# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json
register = template.Library()
@register.filter
def jsonify(list):
return mark_safe(json.dumps(list))
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
var value = JSON.parse(document.getElementById('hello-data').textContent);
我会在模板中执行以下操作:
<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>
var条款=[
{文章列表%中的文章为%0}
{%if不是forloop.first%},{%endif%}
{
标题:“{article.title}}”,
slug:“{article.slug}}”,
内容:“{article.content}}”,
作者:[
{article.authors.all%中的作者为%}
{%if不是forloop.first%},{%endif%}
{
名字:“{{author.first_name}}”,
姓氏:“{{author.last_name}}”,
}
{%endfor%}
]
}
{%endfor%}
]
如果您的问题措辞有点糟糕,并且不打算在
标记中插入代码,并且出于某种原因确实需要JSON,我只需在视图中循环并创建一个dict
列表,JSON序列化该列表没有问题,理解JavaScript没有问题。您的问题是,您的需求常常没有得到充分的说明。您希望JSON看起来像什么?你说你想“序列化queryset”,但格式是什么?您想要每个模型实例中的所有字段、一个选择,还是只想要unicode表示?当你回答了这个问题,你就会知道如何解决你的问题
例如,一种方法可能是使用values
queryset方法为每个实例输出字段字典,并将其序列化(您需要首先将其转换为列表):
你必须把绳子标记为安全的,以确保它不会逃脱 在我的一个项目中,我这样使用它:
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)
# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json
register = template.Library()
@register.filter
def jsonify(list):
return mark_safe(json.dumps(list))
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
var value = JSON.parse(document.getElementById('hello-data').textContent);
在模板中
{% load jsonify %}
<script type="text/javascript" >
var js_list = {{ python_list|jsonify|escapejs }};
</script>
# template.html
<script>
console.log({{units|safe}});
</script>
{%load jsonify%}
var js_list={{python_list | jsonify | escapejs}};
但您可能更愿意在模板中添加mark|u safe或使用| safe来避免所有
内容
如果问题是处理复杂的python对象,那么您可能必须执行如下处理程序:好的,我找到了解决方案 主要是因为没有引用结果。当Javascript试图解析对象时,未将其识别为字符串 因此,第一步是:
var js_list = {{django_list}};
改为:
var js_list = "{{django_list}}";
在这之后,我意识到Django正在转义字符,所以我不得不这样替换它们:
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)
# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json
register = template.Library()
@register.filter
def jsonify(list):
return mark_safe(json.dumps(list))
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
var value = JSON.parse(document.getElementById('hello-data').textContent);
但这不起作用,因为它会与引号混淆
最后,我找到了一种避免在将其发送到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 );
var myDjangoList=(“{django|u list | safe}”)。替换(/&(l | g | quo)t;/g,函数(a,b){
返回{
l:“,
“是吗?”
}[b] );
}));
myDjangoList=myDjangoList.replace(/u'/g,'\'')
myDjangoList=myDjangoList.replace(/'/g,'\'')
myData=JSON.parse(myDjangoList);
我相信这是可以改进的,我把这个告诉你;)
谢谢你的回答
希望对别人有帮助 Django为您正在尝试执行的场景提供内置帮助。事情是这样的:
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)
# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json
register = template.Library()
@register.filter
def jsonify(list):
return mark_safe(json.dumps(list))
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
var value = JSON.parse(document.getElementById('hello-data').textContent);
视图中有一个python序列、列表、字典等,我们称之为py\u对象
。一种方法是在将其传递给渲染引擎之前对其进行jsonify
from django.shortcuts import render_to_response
import json
然后以后像这样使用
render_to_response('mypage.html',{'js_object':json.dumps(py_object)})
data = {{ js_object|safe }}
在模板中,然后使用safe
过滤器将已经jsonized的对象从python导入javascript,如下所示
render_to_response('mypage.html',{'js_object':json.dumps(py_object)})
data = {{ js_object|safe }}
我希望这能解决您的问题。编辑:请不要使用这种方法,请参阅@agconti的答案 使用escapejs过滤器: 倾销清单的例子:
var foo = [{% for x in y %}'{{ x|escapejs }}',{% endfor %}]
同样的问题,“更好”(最近)的答案:
答复如下:
更好的方法是使用DjangoJSONEncoder。它支持十进制
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)
非常容易使用。禁止通过跳圈来转换个人
要浮动的字段
更新:将答案更改为使用内置json而不是simplejson
这个答案在我的谷歌搜索中经常出现,而且有很多视图,所以更新它并避免其他人从中挖掘似乎是个好主意。假设Django 1.5您可以在Django中结合使用和内置过滤器
var json_string = unescape({{json_list | safe | escapejs}});
var json_data = JSON.parse(json_string);
综合答案(my env:Django 2.0)
In views.py
import json
data= []
// fil the list
context['mydata'] = json.dumps({'data':data})
模板中
<script type="text/javascript">
var mydataString = "{{mydata|escapejs}}";
console.log(JSON.parse(mydataString));
</script>
var mydataString=“{mydata | escapejs}}”;
log(JSON.parse(mydataString));
自从Django 2.1以来,就有了。从文档中:
json_脚本
将Python对象安全地输出为JSON,并封装在标记中,
可以与JavaScript一起使用
参数:标记的HTML“id”
例如:
{{ value|json_script:"hello-data" }}
如果值是dictionary{'hello':'world'}
,则输出为:
<script id="hello-data" type="application/json">
{"hello": "world"}
</script>
XSS攻击通过转义字符“”和“&”来缓解。对于
示例:如果值为{'hello':'world&;}
,则输出为:
<script id="hello-data" type="application/json">
{"hello": "world\\u003C/script\\u003E\\u0026amp;"}
</script>
{“你好”:“world\\u003C/script\\u003E\\u0026amp;”}
这是兼容的
具有严格的内容安全策略,禁止在页面脚本中使用
执行。它还维护