在 Django 中安全传递 JSON 数据到前端的正确方法 在 Django 项目里,一个常见的需求是把后端查询到的结构化数据——比如用户的体重记录——传递给前端 Ja vaScript,以便绘制图表或实现动态交互。然而,这里有个高频“踩坑点”:很多开发者会直接把 Python 的字面量(例如一个

在 Django 项目里,一个常见的需求是把后端查询到的结构化数据——比如用户的体重记录——传递给前端 Ja vaScript,以便绘制图表或实现动态交互。然而,这里有个高频“踩坑点”:很多开发者会直接把 Python 的字面量(例如一个列表或字典)塞进 HTML 的 `data-*` 属性里。这种做法不仅无效,而且相当危险。你得到的其实是 Python 的 `repr()` 字符串表示,里面充斥着单引号,特殊字符也没有被转义,这根本不是符合 RFC 8259 规范的标准 JSON。结果就是,前端的 `JSON.parse()` 会毫不犹豫地抛出一个语法错误:`SyntaxError: expected property name or '}'`。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
Django 本身并不会帮你自动完成 JSON 序列化,这一步必须由开发者显式调用 Python 标准库的 `json.dumps()` 来完成。这个函数确保了输出的字符串是“干净”的:
那么,如何修正视图代码呢?来看一个改造后的例子:
import json # 推荐显式 import,更清晰
from django.core.paginator import Paginator
from django.shortcuts import render, redirect
from .models import WeightRecord, Profile
from .forms import WeightLogForm
def profile_page(request):
if request.method == 'POST':
form = WeightLogForm(request.POST)
if form.is_valid():
weight_log = form.sa ve(commit=False)
weight_log.profile = Profile.objects.get(user=request.user)
weight_log.sa ve()
return redirect('profile')
else:
form = WeightLogForm()
user_weight_log = WeightRecord.objects.filter(
profile__user=request.user
).order_by('-entry_date')
paginator = Paginator(user_weight_log, 10)
page = request.GET.get('page')
try:
user_weight_log = paginator.page(page)
except PageNotAnInteger:
user_weight_log = paginator.page(1)
except EmptyPage:
user_weight_log = paginator.page(paginator.num_pages)
# 关键修正:用 json.dumps() 生成标准 JSON 字符串
serialized_data = json.dumps([
{
'weight': str(record.weight),
'entry_date': record.entry_date.strftime('%Y-%m-%d')
}
for record in user_weight_log
])
return render(request, 'profile.html', {
'user_weight_log': user_weight_log,
'form': form,
'weight_data': serialized_data # 此时已是合法 JSON 字符串
})
在对应的模板中,由于 `json.dumps()` 输出的已经是安全的纯文本字符串(不包含 `<`、`>`、`&` 等 HTML 特殊字符),我们仍然需要使用 `|safe` 过滤器来告诉 Django 不要对它进行额外的 HTML 转义:
这样一来,前端 Ja vaScript 就能安全、顺畅地解析数据了:
const weightDataElement = document.getElementById('weight-data');
const weightDataJSON = weightDataElement.getAttribute('data-weight-data');
const weightData = JSON.parse(weightDataJSON); // 现在完全合法
console.log(weightData); // [{weight: "122.00", entry_date: "2023-09-28"}, ...]