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

如何将Django视图/模板数据传入静态JavaScript文件?

解决方案:无需嵌入整个JS文件传递Django模型数据到maps.js

你的问题核心在于:maps.js里的locations变量是自执行函数的局部变量,外部提前定义的同名变量无法被它访问。下面是几个更优雅的解决思路,不用把上万行JS塞进模板:

方案1:暴露全局数据,修改maps.js读取全局变量

首先在模板中把Django模型数据渲染成全局变量,然后调整maps.js从全局变量获取数据:

模板代码(template.html)

<!-- 先渲染Django模型数据为全局变量 -->
<script>
// 使用window对象确保全局可访问
window.mapLocations = [
  {% for model in query_list %}
    [
      locationData(
        'link_to',
        'img_url',
        '{{ model.name|escapejs }}',
        '{{ model.address|escapejs }}',
        '5',
        '10'
      ),
      {{ model.latitude }},
      {{ model.longitude }},
      {{ forloop.counter }},
      '{{ model.icon|escapejs }}'
    ]{% if not forloop.last %},{% endif %}
  {% endfor %}
];
</script>
<!-- 加载原maps.js文件 -->
<script type="text/javascript" src="{% static 'base/scripts/maps.js' %}"></script>

修改maps.js代码

把原来硬编码的locations数组替换为读取全局变量(保留默认值作为 fallback):

(function($){ "use strict";
function mainMap() {
var ib = new InfoBox();
// Infobox Output
function locationData(locationURL,locationImg,locationTitle, locationAddress, locationRating, locationRatingCounter) {
return('SOME_HTML_WITH_VARIABLES')
}
// Locations - 优先使用全局传入的数据,没有则用默认值
var locations = window.mapLocations || [
[ locationData('listings-single-page.html','images/listing-item-01.jpg',"Tom's Restaurant",'964 School Street, New York', '3.5', '12'), 40.94401669296697, -74.16938781738281, 1, '<i class="im im-icon-Chef-Hat"></i>'],
];
// ... 后续地图初始化逻辑 ...
}
mainMap();
})(jQuery);

方案2:通过DOM data属性传递数据

把数据挂载到隐藏的DOM元素上,让maps.js从DOM读取数据,无需修改全局变量:

模板代码(template.html)

<!-- 隐藏的DOM元素,存储地图数据 -->
<div id="map-data" style="display: none" 
     data-locations='[
       {% for model in query_list %}
         [
           "{{ model.name|escapejs }}",
           "{{ model.address|escapejs }}",
           {{ model.latitude }},
           {{ model.longitude }},
           {{ forloop.counter }},
           "{{ model.icon|escapejs }}"
         ]{% if not forloop.last %},{% endif %}
       {% endfor %}
     ]'>
</div>

<script type="text/javascript" src="{% static 'base/scripts/maps.js' %}"></script>

修改maps.js代码

从DOM元素读取数据并生成locations数组:

(function($){ "use strict";
function mainMap() {
var ib = new InfoBox();
// Infobox Output
function locationData(locationURL,locationImg,locationTitle, locationAddress, locationRating, locationRatingCounter) {
return('SOME_HTML_WITH_VARIABLES')
}
// 从DOM读取数据
var mapDataEl = document.getElementById('map-data');
var rawLocations = JSON.parse(mapDataEl.getAttribute('data-locations'));
// 转换为符合要求的locations格式
var locations = rawLocations.map(function(item) {
  return [
    locationData('link_to', 'img_url', item[0], item[1], '5', '10'),
    item[2],
    item[3],
    item[4],
    item[5]
  ];
});
// 如果没有数据则用默认值
if (!locations.length) {
  locations = [
    [ locationData('listings-single-page.html','images/listing-item-01.jpg',"Tom's Restaurant",'964 School Street, New York', '3.5', '12'), 40.94401669296697, -74.16938781738281, 1, '<i class="im im-icon-Chef-Hat"></i>'],
  ];
}
// ... 后续地图初始化逻辑 ...
}
mainMap();
})(jQuery);

方案3:封装地图初始化函数,通过参数接收数据

把maps.js的逻辑改成可调用的初始化函数,直接传入数据,这是最符合模块化的方案:

修改maps.js代码

暴露一个全局初始化函数,接收locationsData参数:

(function($){ "use strict";
// 暴露全局初始化函数
window.initMainMap = function(locationsData) {
  function mainMap() {
    var ib = new InfoBox();
    // Infobox Output
    function locationData(locationURL,locationImg,locationTitle, locationAddress, locationRating, locationRatingCounter) {
      return('SOME_HTML_WITH_VARIABLES')
    }
    // 使用传入的数据,没有则用默认值
    var locations = locationsData || [
      [ locationData('listings-single-page.html','images/listing-item-01.jpg',"Tom's Restaurant",'964 School Street, New York', '3.5', '12'), 40.94401669296697, -74.16938781738281, 1, '<i class="im im-icon-Chef-Hat"></i>'],
    ];
    // ... 后续地图初始化逻辑 ...
  }
  mainMap();
};
})(jQuery);

模板代码(template.html)

<script type="text/javascript" src="{% static 'base/scripts/maps.js' %}"></script>
<!-- 渲染数据并调用初始化函数 -->
<script>
var mapLocations = [
  {% for model in query_list %}
    [
      locationData(
        'link_to',
        'img_url',
        '{{ model.name|escapejs }}',
        '{{ model.address|escapejs }}',
        '5',
        '10'
      ),
      {{ model.latitude }},
      {{ model.longitude }},
      {{ forloop.counter }},
      '{{ model.icon|escapejs }}'
    ]{% if not forloop.last %},{% endif %}
  {% endfor %}
];
// 调用初始化函数并传入数据
window.initMainMap(mapLocations);
</script>

关键注意事项

  • 一定要使用|escapejs过滤器处理Django模型中的字符串字段,避免引号、换行符等破坏JS语法,同时防止XSS攻击。
  • 如果locationData的参数(比如link_to、img_url)也需要从Django模型获取,直接替换模板中的硬编码值即可。

内容的提问来源于stack exchange,提问作者GRS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:02:10