n.b.请参阅底部的 2018 年更新
我建议不要在您的 Django 模板中添加大量 JavaScript - 它往往难以编写和调试,尤其是在您的项目扩展时。相反,请尝试在模板加载的单独脚本文件中编写所有 JavaScript,并在模板中仅包含 JSON 数据对象。这允许您执行诸如通过 JSLint 之类的方式运行整个 JavaScript 应用程序、缩小它等操作,并且您可以使用静态 HTML 文件对其进行测试,而不依赖于您的 Django 应用程序。使用 simplejson 之类的库还可以节省您编写繁琐的序列化代码的时间。
如果您不假设您正在构建一个 AJAX 应用程序,则可以这样简单地完成:
在视图中:
from django.utils import simplejson
def view(request, …):
js_data = simplejson.dumps(my_dict)
…
render_template_to_response("my_template.html", {"my_data": js_data, …})
在模板中:
<script type="text/javascript">
data_from_django = {{ my_data }};
widget.init(data_from_django);
</script>
请注意,数据的类型很重要:如果my_data 是一个简单的数字或来自不包含 HTML 的受控源的字符串,例如格式化的日期,则不需要特殊处理。如果可能有用户提供的不受信任的数据,您将需要使用escape 或escapejs 过滤器之类的东西对其进行清理,并确保您的JavaScript 安全地处理数据以避免cross-site scripting 攻击。
就日期而言,您可能还想考虑如何传递日期。我几乎总是发现将它们作为 Unix 时间戳传递是最容易的:
在 Django 中:
time_t = time.mktime(my_date.timetuple())
在 JavaScript 中,假设您使用上述 sn-p 的结果完成了类似 time_t = {{ time_t }} 的操作:
my_date = new Date();
my_date.setTime(time_t*1000);
最后,请注意 UTC - 您需要让 Python 和 Django 日期函数以 UTC 交换数据,以避免与用户本地时间发生尴尬的变化。
编辑:请注意,javascript 中的 setTime 以毫秒为单位,而 time.mktime 的输出为秒。这就是为什么我们需要乘以 1000
2018 年更新:我仍然喜欢 JSON 来处理复杂值,但在这十年间the HTML5 data API 已经达到了near universal browser support 并且传递简单(非列表/字典)值非常方便,特别是如果你可能想要CSS 规则基于这些值应用,您不必关心不受支持的 Internet Explorer 版本。
<div id="my-widget" data-view-mode="tabular">…</div>
let myWidget = document.getElementById("my-widget");
console.log(myWidget.dataset.viewMode); // Prints tabular
somethingElse.addEventListener('click', evt => {
myWidget.dataset.viewMode = "list";
});
如果您想在 Django 模板中设置初始视图状态并让它在 JavaScript 更新 data- 属性时自动更新,这是一种向 CSS 公开数据的好方法。我将其用于隐藏进度小部件等事情,直到用户选择要处理的内容或根据获取结果有条件地显示/隐藏错误,甚至使用诸如 #some-element::after { content: attr(data-active-transfers); } 之类的 CSS 显示活动记录计数。