解决Django传递的列表在JavaScript中JSON.parse报错问题
解决Django传递Python列表到JavaScript的JSON解析错误
问题场景
将Django生成的包含布尔值的列表传递到模板index.html的data-likes属性中,前端尝试用JSON.parse解析时抛出语法错误:
Uncaught SyntaxError: Unexpected token 'F', "[[0, False], [0"... is not valid JSON
传递的列表示例:
[[0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [0, False], [2, True], [2, True]]
对应模板代码:
<div class="like-component" data-post-id="{{post.id}}" data-likes="{{likes}}"></div>
前端JavaScript代码:
function renderlikeposts(){ const likeComponents = document.querySelectorAll('.like-component'); likeComponents.forEach(component => { const postId = component.dataset.postId; const list = JSON.parse(component.dataset.likes); const likes = component.dataset.likes[postId-1][0]; const liked = Boolean(component.dataset.likes[postId-1][1]); ReactDOM.render(<Like postId={postId} likes={likes} liked={liked} list={list} />, component); }); }
问题原因
Django直接渲染Python列表时,会输出Python风格的布尔值False/True,但JSON规范要求布尔值必须是小写的false/true,格式不兼容导致JSON.parse解析失败。此外原JS代码中直接对dataset.likes字符串进行数组索引操作,这是错误的——必须先解析为数组才能访问元素。
解决方案
方案1:后端用JSON序列化(推荐)
在Django视图中使用json.dumps将列表序列化为标准JSON字符串,再传递到模板:
import json def your_view(request): # 假设likes_list是你要传递的Python列表 likes_list = [[0, False], [0, False], ..., [2, True], [2, True]] context = { 'likes': json.dumps(likes_list), 'post': post # 你的post对象 } return render(request, 'index.html', context)
模板中使用|safe过滤器避免Django转义JSON字符串的引号:
<div class="like-component" data-post-id="{{post.id}}" data-likes="{{likes|safe}}"></div>
前端代码修正数组访问逻辑后直接解析:
function renderlikeposts(){ const likeComponents = document.querySelectorAll('.like-component'); likeComponents.forEach(component => { const postId = component.dataset.postId; const list = JSON.parse(component.dataset.likes); const likes = list[postId-1][0]; const liked = list[postId-1][1]; // 解析后直接是布尔值,无需转Boolean ReactDOM.render(<Like postId={postId} likes={likes} liked={liked} list={list} />, component); }); }
方案2:前端替换布尔值格式
如果无法修改后端代码,可在前端先将字符串中的False/True替换为JSON兼容的false/true,再解析:
function renderlikeposts(){ const likeComponents = document.querySelectorAll('.like-component'); likeComponents.forEach(component => { const postId = component.dataset.postId; // 替换Python布尔值为JSON规范格式 const normalizedLikes = component.dataset.likes .replace(/False/g, 'false') .replace(/True/g, 'true'); const list = JSON.parse(normalizedLikes); const likes = list[postId-1][0]; const liked = list[postId-1][1]; ReactDOM.render(<Like postId={postId} likes={likes} liked={liked} list={list} />, component); }); }
内容的提问来源于stack exchange,提问作者Zeyad moussa
相关产品推荐
相关产品推荐

