
本文详解如何将 django 视图中构造的 python 字典(如卡片列表)正确序列化为 json,并在前端 javascript 中可靠解析、访问和渲染,避免因特殊字符转义或格式错误导致解析失败。
本文详解如何将 django 视图中构造的 python 字典(如卡片列表)正确序列化为 json,并在前端 javascript 中可靠解析、访问和渲染,避免因特殊字符转义或格式错误导致解析失败。
在 Django 开发中,常需将后端模型数据(如 Card 对象列表)传递给前端 JavaScript 进行交互式操作(例如制作抽认卡应用)。但Python 字典无法被 JavaScript 直接读取——模板中直接写 {{ cards }} 会生成带单引号、Unicode 转义、无引号键名的字符串(如 {'front': 'Hello', 'back': '世界'}),这不符合 JSON 标准,JSON.parse() 会抛出语法错误。
✅ 正确做法是:在视图中显式序列化为标准 JSON 字符串,再通过 HTML data-* 属性安全注入。
1. 后端:使用 json.dumps() 序列化(推荐)
修改 views.py,导入 json 并对 cards 列表调用 json.dumps():
import json
from django.shortcuts import render, get_object_or_404
from django.forms import model_to_dict # 更简洁地提取字段
def learn(request, deck_id):
deck = get_object_or_404(Deck, pk=deck_id)
cards_queryset = deck.cards.all()
# 方案一:手动构造字典(清晰可控)
cards = [{'front': card.front, 'back': card.back} for card in cards_queryset]
# 方案二:使用 model_to_dict(更健壮,自动处理字段类型)
# cards = [model_to_dict(card, fields=['front', 'back']) for card in cards_queryset]
return render(request, 'srs/learn.html', {
'deck': deck,
'cards': json.dumps(cards), # ← 关键:转为标准 JSON 字符串
})⚠️ 注意:
json.dumps()会自动处理中文、引号、换行等特殊字符,输出如[{"front": "Hello", "back": "世界"}, ...]—— 这是合法 JSON,可被 JS 安全解析。
Alibabacloud Sdk Client Initialization For Java下载在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
2. 前端:从 data-* 属性读取并解析
在模板中,将 JSON 字符串存入 data-cards 属性(无需额外转义):
<!-- learn.html -->
<div id="cards-var" data-cards="{{ cards }}"></div>
<script src="{% static 'srs/learn.js' %}"></script>在 learn.js 中解析并使用:
// 获取 data 属性值(字符串)
const cardsData = document.getElementById('cards-var').dataset.cards;
// 解析为 JavaScript 数组
const cards = JSON.parse(cardsData);
// 示例:显示第一张卡片
console.log('第一张卡片正面:', cards[0].front); // "Hello"
console.log('第一张卡片背面:', cards[0].back); // "世界"
// 实际应用:绑定按钮事件
document.getElementById('show-answer').addEventListener('click', () => {
const frontEl = document.querySelector('.front');
const backEl = document.querySelector('.back');
// 假设当前显示第 0 张(可扩展为状态管理)
frontEl.textContent = cards[0].front;
backEl.textContent = cards[0].back;
});
document.getElementById('next-card').addEventListener('click', () => {
// 此处可添加索引逻辑,遍历 cards 数组
console.log('切换到下一张卡片...');
});✅ 关键要点总结
-
永远不要直接在模板中使用
{{ cards }}渲染 Python 对象给 JS —— 它不是 JSON。 -
必须使用
json.dumps()(Django)或JSON.stringify()(JS)生成标准 JSON 字符串。 - *优先通过 `data-
属性传值**,比内联<script>` 更安全、更易维护。</script> - 若需传输复杂模型(含日期、外键等),考虑 Django 的
serializers模块,它支持json,xml等格式,并能自动序列化关联字段。 - 浏览器控制台中验证:
console.log(cardsData)应显示纯 JSON 字符串;console.log(cards)应显示解析后的数组对象。
遵循此流程,即可在 Django + JavaScript 应用中稳定、高效地传递和操作结构化数据。


















