Flask传递字典列表至前端模板:如何转为JSON并遍历?
搞定Flask模板中JSON解析的问题
嘿,我一眼就看到你代码里的问题了——你在处理JSON字符串的时候多套了一层不必要的包裹,导致解析后还是字符串类型。咱们一步步来解决:
问题出在哪?
你的Flask视图已经用json.dumps(result_list)把结果转成了合法的JSON字符串,但在模板里写的这段代码:
var res = JSON.parse(JSON.stringify('{{result | tojson | safe}}'));
犯了两个小错误:
- 你给
{{result}}加了单引号,把原本的JSON字符串变成了一个带引号的普通字符串(相当于把JSON又当成了字符串内容) - 多做了
JSON.stringify操作,这完全是画蛇添足,反而把问题复杂化了
怎么修复?
第一步:简化视图传递(可选但更规范)
其实Flask自带的tojson过滤器可以直接把Python列表转成JSON,你完全可以不用自己调用json.dumps,视图函数改成这样更清爽:
def prediction(): # ... 其他代码不变 ... return render_template('prediction.html', result=result_list)
当然如果你坚持用json.dumps也没问题,后面的模板处理对应调整就行。
第二步:修正模板里的JS代码
不管视图传的是Python列表还是已转好的JSON字符串,核心是不要给JSON加额外的引号,直接让它变成JS里的对象/数组:
情况1:视图传Python对象(推荐)
直接用tojson | safe输出,然后直接赋值给变量(因为输出的就是合法的JS数组语法):
var res = {{ result | tojson | safe }};
这时候console.log(typeof(res))就会显示object了,完美!
情况2:视图传已用json.dumps转好的字符串
那你就直接去掉引号,用JSON.parse解析:
var res = JSON.parse({{ result | safe }});
因为{{ result | safe }}会直接输出你在视图里转好的JSON字符串,不需要额外包裹。
遍历渲染结果的示例
现在res已经是一个JS数组了,咱们用forEach来遍历渲染到页面上:
var res = {{ result | tojson | safe }}; var predictionDiv = document.getElementById('prediction'); res.forEach(function(item) { // 创建一个卡片元素来展示每条结果 var tweetCard = document.createElement('div'); tweetCard.style = 'border: 1px solid #eee; padding: 15px; margin: 10px 0; border-radius: 8px;'; tweetCard.innerHTML = ` <p><strong>推文内容:</strong> ${item.tweet}</p> <p><strong>情感标签:</strong> <span style="color: ${item.label === 'positive' ? 'green' : item.label === 'negative' ? 'red' : 'gray'}">${item.label}</span></p> <p><strong>置信度:</strong> ${(item.score * 100).toFixed(2)}%</p> <p><strong>处理耗时:</strong> ${item.elapsed_time.toFixed(4)}秒</p> `; predictionDiv.appendChild(tweetCard); });
完整的修复后模板代码
{% extends 'base.html' %} {% block head %} <title>Prediction | Sentiment Analysis</title> {% endblock %} {% block body %} <div id="prediction"></div> <script type="text/javascript"> // 正确获取并转为JS数组 var res = {{ result | tojson | safe }}; console.log(res, typeof(res)); // 现在会显示object类型 // 遍历渲染所有结果 const container = document.getElementById('prediction'); res.forEach(tweet => { const card = document.createElement('div'); card.style.cssText = 'border: 1px solid #ddd; padding: 12px; margin-bottom: 10px; border-radius: 4px;'; card.innerHTML = ` <h4 style="margin-top: 0;">推文</h4> <p>${tweet.tweet}</p> <div style="margin-top: 8px;"> <span>情感: <strong>${tweet.label}</strong></span> <span style="margin-left: 20px;">置信度: ${tweet.score.toFixed(3)}</span> <span style="margin-left: 20px;">耗时: ${tweet.elapsed_time.toFixed(4)}s</span> </div> `; container.appendChild(card); }); </script> {% endblock %}
内容的提问来源于stack exchange,提问作者Sanket Manmode
相关产品推荐
相关产品推荐

