将对象从Django传递到Javascript DOM

将对象从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

我试图用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 = 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;”}
这是兼容的 具有严格的内容安全策略,禁止在页面脚本中使用 执行。它还维护