通过Django将Python数据传递给JavaScript
我使用Django和Apache来提供网页。 我的JavaScript代码当前包含一个数据对象,其值将根据用户从选项菜单中的select,显示在各种HTML小部件中。 我想从Python字典中派生这些数据。 我想我知道如何在HTML中embeddedJavaScript代码,但是如何将数据对象embedded到该脚本中(即时),以便脚本的function可以使用它?
换一种说法,我想从Python字典创build一个JavaScript对象或数组,然后将该对象插入到JavaScript代码中,然后将该JavaScript代码插入到HTML中。
我想这个结构(例如embedded在JavaScript代码中的variables中的数据)是次优的,但作为新手我不知道替代scheme。 我已经看过Django序列化函数的书写,但是直到我可以将数据放入我的JavaScript代码中,这些function并没有帮助。
我还没有使用像jQuery这样的JavaScript库。
我build议不要在你的Django模板中join大量的JavaScript,特别是当你的项目扩展的时候,它往往很难编写和debugging。 相反,请尝试将所有JavaScript写入模板加载的单独脚本文件中,并在模板中仅包含一个JSON数据对象。 这可以让你做一些事情,比如像JSLint一样运行你的整个JavaScript应用程序,缩小它等,你可以用一个静态的HTML文件testing它,而不需要依赖你的Django应用程序。 使用像simplejson这样的库还可以节省编写单调乏味的序列化代码的时间。
如果你不假设你正在构build一个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>
请注意,数据的types很重要:如果my_data
是简单数字或来自受控源(不包含HTML)的string(如格式化date),则不需要进行特殊处理。 如果可能有用户提供的不可信数据,则需要使用类似escape或escapejsfilter的方式进行清理,并确保JavaScript安全地处理数据以避免跨站点脚本攻击。
就date而言,您可能还想考虑如何通过date。 我几乎总是发现把它们作为Unix时间戳传递是最容易的:
在Django中:
time_t = time.mktime(my_date.timetuple())
在JavaScript中,假设您已经完成了类似time_t = {{ time_t }}
,并显示了以上代码片段的结果:
my_date = new Date(); my_date.setTime(time_t*1000);
最后,请注意UTC – 您将希望Python和Djangodate函数以UTC来交换数据,以避免用户当地时间的尴尬转变。
编辑:请注意,JavaScript中的setTime是以毫秒为单位,而time.mktime的输出是秒。 这就是为什么我们需要乘以1000
对于任何可能遇到问题的人,请确保您在模板中以安全模式呈现您的json对象。 你可以像这样手动设置
<script type="text/javascript"> data_from_django = {{ my_data|safe }}; widget.init(data_from_django); </script>
您可以在.html模板中包含<script>
标签,然后构build您的数据结构,但对您来说很方便。 模板语言不仅用于HTML,还可以用来实现Javascript对象文字。
Paul是对的:最好使用json模块创build一个JSONstring,然后将该string插入到模板中。 这将最好地处理报价问题,并轻松处理深层次的结构。
这是不理想的。 你有没有考虑过使用django的内置序列化器来传递数据为JSON?
看到相关的回应这个问题 。 一种select是使用jsonpickle在Python对象和JSON / Javascript对象之间进行序列化。 它包装simplejson并处理通常不被simplejson接受的东西。
把Java脚本embedded到Django模板中总是不好的主意。
相反 ,因为这个规则有一些例外。
一切都取决于您的Java脚本代码网站和function。
最好是单独的静态文件,如JS,但问题是每个单独的文件需要另一个连接/ GET /请求/响应机制。 有时对于小的一个,两个内码代码os JS把这个放入模板,然后使用django templatetags机制 – 你可以使用在其他模板;)
关于对象 – 相同。 如果你的网站有AJAX的build设/ web2.0喜欢 – 你可以达到很好的效果,把一些计数/math运算到客户端。 如果对象很小 – embedded到模板中,如果很大 – 在另一个连接中响应它们以避免用户挂起页面。