如何在Django中将模态框的content_id传递至结账处理脚本
问题描述
在Django模板首页循环展示多个条目,点击条目会弹出模态框,通过JSONResponse预填充该条目的相关数据。现在需要创建结账会话,但无法将模态框对应条目的content_id传递到结账处理脚本中。
解决方案
下面提供几种简单直接的实现方式:
方案1:用全局变量存储当前content_id
在打开模态框时,将目标content_id存入全局变量,结账时直接调用该变量即可。
修改模态框处理脚本
let modal = document.getElementById("modal"); modal.style.display = "none"; // 全局变量存储当前选中的content_id let currentContentId = null; function modalHandler(val, content_id) { if (val) { // 保存当前条目content_id currentContentId = content_id; let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { let data = JSON.parse(this.responseText); document.getElementById("subtotal").innerHTML = data.subtotal; document.getElementById("taxes").innerHTML = data.taxes; document.getElementById("website_fee").innerHTML = data.website_fee; document.getElementById("total").innerHTML = data.total; fadeIn(modal); } }; xhr.open("GET", "/modal-content/" + content_id + "/", true); xhr.send(); } else { fadeOut(modal); // 关闭模态框时清空变量 currentContentId = null; } }
修改结账处理脚本
var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { // 校验是否选中有效条目 if (!currentContentId) return; // 动态生成结账URL(替换Django URL模板中的占位符) const checkoutUrl = "{% url 'checkout' 0 %}".replace('0', currentContentId); fetch(checkoutUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' // 必须携带CSRF Token,Django POST请求要求 }, data: JSON.stringify({ amount: document.getElementById("total").innerHTML * 100, description: "内容订阅", }), }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); });
方案2:将content_id存入模态框的data属性
把content_id绑定到模态框元素的自定义属性中,结账时直接读取该属性值。
修改模态框处理脚本
function modalHandler(val, content_id) { if (val) { // 将content_id存入模态框的data属性 modal.setAttribute('data-content-id', content_id); // ... 原有XHR请求及填充逻辑不变 } else { fadeOut(modal); // 关闭时移除属性 modal.removeAttribute('data-content-id'); } }
修改结账处理脚本
checkoutButton.addEventListener('click', function() { // 从模态框属性中获取content_id const contentId = modal.getAttribute('data-content-id'); if (!contentId) return; const checkoutUrl = "{% url 'checkout' 0 %}".replace('0', contentId); fetch(checkoutUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' }, data: JSON.stringify({ amount: document.getElementById("total").innerHTML * 100, description: "内容订阅", }), }) // ... 后续逻辑同方案1 });
方案3:从JSON响应中提取content_id
利用后端返回的JSON数据中的content_id字段(你的modal_content_view已返回该字段),直接存储使用。
修改模态框处理脚本的XHR回调
xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { let data = JSON.parse(this.responseText); // 从后端返回的JSON中获取content_id currentContentId = data.content_id; // ... 原有填充模态框逻辑 fadeIn(modal); } };
后续结账脚本同方案1即可。
额外注意事项
- 移除视图中的
@csrf_exempt装饰器,通过请求头携带X-CSRFToken更安全。 - 如果金额等数据需要精准性,建议从后端返回的JSON中读取,而非模态框DOM元素的innerHTML。
内容的提问来源于stack exchange,提问作者victor
相关产品推荐
相关产品推荐

