【问题标题】:Python datastructures into js datastructures using jinja2 template (lists and dicts)使用 jinja2 模板(列表和字典)将 Python 数据结构转换为 js 数据结构
【发布时间】:2014-05-27 11:34:00
【问题描述】:

我有一个与这个问题非常相似的问题,Python datastructures into js datastructures using Django templates (lists and dicts),但下一步 - python 中作为字符串的变量名如何成为 javascript 对象?

所以在 python 中我有这个:

data = [{'year': 2006, 'books': 54, 'author': 'fred'},
    {'year': 2007, 'books': 43, 'author': 'sue'},
    {'year': 2008, 'books': 41, 'author': 'bill'},
    {'year': 2009, 'books': 44, 'author': 'alex'},
    {'year': 2010, 'books': 35, 'author': 'fred'}]

我可以通过 {{ data | 输出到我的 javascript安全 }}

但我希望我的 javascript 看起来像这样:

var data = [{year: 2006, books: 54, author: 'fred'},
    {year: 2007, books: 43, author: 'sue'},
    {year: 2008, books: 41, author: 'bill'},
    {year: 2009, books: 44, author: 'alex'},
    {year: 2010, books: 35, author: 'fred'}];

而现在它是这样出现的:

var data = [{'year': 2006, 'books': 54, 'author': 'fred'},
    {'year': 2007, 'books': 43, 'author': 'sue'},
    {'year': 2008, 'books': 41, 'author': 'bill'},
    {'year': 2009, 'books': 44, 'author': 'alex'},
    {'year': 2010, 'books': 35, 'author': 'fred'}];

有没有办法做到这一点?

非常感谢, 标记

【问题讨论】:

  • 我认为JSON.parse(data) 可以满足您的需求。
  • 一般来说,这些数据结构的通信非常容易——在客户端JSON.stringify/JSON.parse,在服务器上json.dumps/json.loads
  • 感谢您的指导!我想我可能有不正确的语法,因为我在这个小提琴中尝试了你的建议,比如 JSON.parse 但它不起作用:jsfiddle.net/Bh8et/1 在询问之前我也尝试了很多 JSON.stringify 的解决方案,但看不到这是如何创建非字符串变量的。

标签: javascript python list jinja2


【解决方案1】:

Flask 中包含的tojson filter 负责生成一个有效的 Javascript 子集,该子集也是 HTML 安全的:

var data = {{ data|tojson|safe }};

如果你没有使用 Flask,那么 register a custom filter 喜欢:

import json

def tojson(obj):
    """Produce HTML-safe JSON"""
    return (json.dumps(obj)
                .replace(u'<', u'\\u003c')
                .replace(u'>', u'\\u003e')
                .replace(u'&', u'\\u0026')
                .replace(u"'", u'\\u0027'))

【讨论】:

  • @traceur:对于 JSON 允许但 JS 不允许的两个代码点,JSON 是 JavaScript except 的完整子集。默认的json.dumps() 设置转义这两个代码点。
  • @traceur:那为什么要使用模板呢?您永远不会在模板上使用闭包编译器,最多只能在模板的 输出 上使用。
  • 非常感谢,我认为过滤器可能是之前建议的方式,但没有使用 Flask。但是,我已经注册了这个过滤器并重新加载了,数据仍然包含字符串——我在模板中使用了 {{ dataChart|tojson|safe }},它在渲染时变成了这样: [{"medium": "organic", "访问“:2059.0},{“中”:“(无)”,“访问”:379.0},{“中”:“推荐”,“访问”:346.0}]
  • @Mark:JavaScript 允许将键作为字符串括在引号中。 {"medium": "referral"}{medium: "referral"} 相同。有这些引号就很好了。
  • @MartijnPieters 但由于某种原因,它在带有引号的 ChartJS chartjs.devexpress.com 中不起作用,我认为它应该这样做,但它拒绝了,所以这次寻找未引用的。也许它以某种方式与图书馆一起设置。
【解决方案2】:

解决方案是 Martijn Pieters 和 traceur 的组合,非常感谢 :D

所以代码的工作版本是:

在 Python 中:

data = [{'year': 2006, 'books': 54, 'author': 'fred'},
{'year': 2007, 'books': 43, 'author': 'sue'},
{'year': 2008, 'books': 41, 'author': 'bill'},
{'year': 2009, 'books': 44, 'author': 'alex'},
{'year': 2010, 'books': 35, 'author': 'fred'}]

....rest of code....

variables = {
    'data' : data
    }
template = JINJA_ENVIRONMENT.get_template('main.html')
self.response.write(template.render(variables))

除上述之外,我还必须为 jinja2 注册一个新的 JSON 过滤器:

JINJA_ENVIRONMENT = jinja2.Environment(
  loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
  autoescape=True,
  extensions=['jinja2.ext.autoescape'])

def tojson(obj):
 """Produce HTML-safe JSON"""
  return (json.dumps(obj)
            .replace(u'<', u'\\u003c')
            .replace(u'>', u'\\u003e')
            .replace(u'&', u'\\u0026')
            .replace(u"'", u'\\u0027'))

JINJA_ENVIRONMENT.filters['tojson'] = tojson

...然后在需要调用此过滤器的 HTML 中将其放置在 javascript 中,但也可以根据 traceur 的注释进行评估。 (我真的不知道为什么)

<script type="text/javascript">
  dataSource = eval('({{ data|tojson|safe }})')
  console.log(dataSource)
  ....do stuff with dataSource....
</script>

dataSource 现在是一个 js 对象,它的格式对我的 ChartJS 可视化来说是正确的。

非常感谢!

【讨论】:

    猜你喜欢
    • 2012-03-21
    • 2018-02-25
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多