You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中处理Django传递的字典数据?

解决Django模板向JS传递卡片数据的问题

核心问题分析

你当前的问题在于直接在模板中使用{{ cards }}输出Python列表,得到的是Python风格的字符串(比如[{'front': 'xxx', ...}]),这种格式不是标准JSON,JS无法直接解析成对象,所以会出现多余的{、[、'符号。

正确的传递方式

方法1:使用Django的json_script过滤器(推荐)

Django内置的json_script过滤器会把Python序列转成安全的JSON字符串,并包裹在<script>标签里,避免XSS风险且格式正确。

修改模板文件:

{% extends "srs/layout.html" %}
{% load static %}

{% block body %}
    <div class="body-container">
        <p class="front"></p>
        <p class="back"></p>
        <button id="show-answer">Show Answer</button>
        <button id="next-card">Next</button>
    </div>

    <!-- 用json_script生成安全的JSON数据 -->
    {{ cards|json_script:"cards-data" }}
    <script src="{% static 'srs/learn.js' %}"></script>
{% endblock %}

方法2:手动转JSON并转义(不推荐,不如方法1安全)

如果不想用json_script,可以在视图中用json.dumps把cards转成JSON字符串,然后在模板中输出:

修改视图函数:

import json
from django.shortcuts import get_object_or_404

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]
    
    # 转成JSON字符串
    cards_json = json.dumps(cards)
    
    return render(request, 'srs/learn.html', {
        'deck': deck,
        'cards_json': cards_json,
    })

然后模板中这样写:

<div id="cards-var" data-cards="{{ cards_json|escapejs }}"></div>

在JS中访问数据

以方法1为例,在learn.js中解析并使用数据:

// 获取JSON数据并解析成JS数组
const cards = JSON.parse(document.getElementById('cards-data').textContent);

// 初始化当前卡片索引
let currentCardIndex = 0;

// 显示当前卡片的正面
function showCurrentCardFront() {
    const frontElement = document.querySelector('.front');
    const backElement = document.querySelector('.back');
    frontElement.textContent = cards[currentCardIndex].front;
    backElement.textContent = ''; // 隐藏背面
}

// 显示当前卡片的背面
function showCurrentCardBack() {
    const backElement = document.querySelector('.back');
    backElement.textContent = cards[currentCardIndex].back;
}

// 切换到下一张卡片
function nextCard() {
    currentCardIndex = (currentCardIndex + 1) % cards.length;
    showCurrentCardFront();
}

// 绑定按钮事件
document.getElementById('show-answer').addEventListener('click', showCurrentCardBack);
document.getElementById('next-card').addEventListener('click', nextCard);

// 页面加载时显示第一张卡片
window.addEventListener('load', showCurrentCardFront);

关于拆分数组的问题

你之前考虑拆分front和back到两个数组,完全没必要。用对象数组(每个元素包含front和back)的方式更符合逻辑,后续维护时能清晰对应每张卡片的正反内容,不会混乱。

内容的提问来源于stack exchange,提问作者harry.exe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:15:06