Django 模板 - 将 Python 列表转换为 JavaScript 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4698220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 17:01:15  来源:igfitidea点击:

Django Template - Convert a Python list into a JavaScript object

javascriptpythondjangodjango-templates

提问by amcashcow

I am working on a Django / Python website. I have a page where I want to display a table of search results. The list of results is passed in to the template as normal.

我在 Django / Python 网站上工作。我有一个页面,我想在其中显示搜索结果表。结果列表照常传递给模板。

I also want to make this list of objects accessible to the JavaScript code.

我还想让 JavaScript 代码可以访问这个对象列表。

My first solution was just create another view that returned JSONformat. But each page load required calling the query twice. So then I tried only downloading the data using the JSON view and printing the table using JavaScript.

我的第一个解决方案是创建另一个返回JSON格式的视图。但是每个页面加载都需要调用两次查询。因此,我尝试仅使用 JSON 视图下载数据并使用 JavaScript 打印表格。

But this is also not desirable as now the presentation layer is mixed into the JavaScript code.

但这也是不可取的,因为现在表示层已混合到 JavaScript 代码中。

Is there a way to create a JavaScript object from the Python list as the page is rendered?

有没有办法在页面呈现时从 Python 列表创建一个 JavaScript 对象?

采纳答案by amcashcow

Solution

解决方案

I created a custom template filter, see 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   

The calls to mark_safe are important. Otherwise Django will escape it.

对 mark_safe 的调用很重要。否则 Django 会逃避它。

In the template:

在模板中:

//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);

Note the single quotes around the template tag.

注意模板标签周围的单引号。

Although my next question would be - is it REALLY safe?

虽然我的下一个问题是 - 它真的安全吗?

Update

更新

An updated version working in django 1.8 of the above template tag that also handles being passed a flat values list, ie. values_list('myfield', flat=True):

在上述模板标签的 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)

回答by Amber

How about a filter that dumps a Python value to JSON? Here's a sample implementation:

将 Python 值转储到 JSON 的过滤器怎么样?这是一个示例实现:

http://djangosnippets.org/snippets/201/

http://djangosnippets.org/snippets/201/

Since a JSON value also happens to be a valid right-hand side for a Javascript assignment, you can simply put something like...

由于 JSON 值也恰好是 Javascript 赋值的有效右侧,因此您可以简单地放置类似...

var results = {{results|jsonify}};

inside your script.

在您的脚本中。

回答by mrvol

Look this answertoo.

也看看这个答案

But it isn't highload way. You must:

但它不是高负载方式。你必须:

a) Create JSON files, place to disk or S3. In case is JSON static

a) 创建 JSON 文件,放置到磁盘或 S3。如果 JSON 是静态的

b) If JSON is dynamic. Generate JSON on separately url (like API) in your app.

b) 如果 JSON 是动态的。在您的应用程序中单独的 url(如 API)上生成 JSON。

And, load by JS directly in any case. For example:

并且,在任何情况下都直接由 JS 加载。例如:

$.ajax('/get_json_file.json')

$.ajax('/get_json_file.json')

P.S.: Sorry for my English.

PS:对不起我的英语。

回答by Flimm

New in Django 2.1: json_script

Django 2.1 中的新功能: json_script

Django 2.1 introduced a new template tag: json_script. It is almost exactly what you are looking for, it might be even better. It converts a Python value into JSON, wrapped in a <script>tag. So this template:

Django 2.1 引入了一个新的模板标签:json_script. 这几乎正​​是您正在寻找的,它可能会更好。它将 Python 值转换为包裹在<script>标签中的JSON 。所以这个模板:

{{ value|json_script:"foobar" }}

... would produce this:

...会产生这个:

<script id="foobar" type="application/json">{"example": "example"}</script>

This is not a normal Javascript <script>tag, it doesn't run, it's just JSON. If you want to access the contents in your Javascript, you can do so like this:

这不是一个普通的 Javascript<script>标签,它不能运行,它只是 JSON。如果要访问 Javascript 中的内容,可以这样做:

var value = JSON.parse(document.getElementById('foobar').textContent);

This tag has been coded so that it is properly escaped, a string with </script>in it won't break anything, for instance.

该标签已被编码,以便正确转义,例如,其中的字符串</script>不会破坏任何内容。